159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * COPYRIGHT (C) 2006,2007
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * ALL RIGHTS RESERVED
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Permission is granted to use, copy, create derivative works
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * and redistribute this software and such derivative works
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * for any purpose, so long as the name of The University of
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Michigan is not used in any advertising or publicity
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * pertaining to the use of distribution of this software
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * without specific, written prior authorization. If the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * above copyright notice or any other identification of the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * University of Michigan is included in any copy of any
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * portion of this software, then the disclaimer below must
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * also be included.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * SUCH DAMAGES.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <stdio.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <stdlib.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <errno.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <string.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include "pkinit.h"
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_server_get_edata(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req * request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _krb5_db_entry_new * client,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _krb5_db_entry_new * server,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan preauth_get_entry_data_proc server_get_entry_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *pa_plugin_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data * data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_server_verify_padata(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _krb5_db_entry_new * client,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *req_pkt,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req * request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_enc_tkt_part * enc_tkt_reply,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data * data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan preauth_get_entry_data_proc server_get_entry_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *pa_plugin_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void **pa_request_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data **e_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_authdata ***authz_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_server_return_padata(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data * padata,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _krb5_db_entry_new * client,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *req_pkt,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req * request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_rep * reply,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _krb5_key_data * client_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_keyblock * encrypting_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data ** send_pa,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan preauth_get_entry_data_proc server_get_entry_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *pa_plugin_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void **pa_request_context);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int pkinit_server_get_flags
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context kcontext, krb5_preauthtype patype);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code pkinit_init_kdc_req_context
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context, void **blob);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void pkinit_fini_kdc_req_context
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context context, void *blob);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int pkinit_server_plugin_init_realm
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context context, const char *realmname,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_context *pplgctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void pkinit_server_plugin_fini_realm
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context context, pkinit_kdc_context plgctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int pkinit_server_plugin_init
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context context, void **blob, const char **realmnames);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void pkinit_server_plugin_fini
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context context, void *blob);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic pkinit_kdc_context pkinit_find_realm_context
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context context, void *pa_plugin_context, krb5_principal princ);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_create_edata(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_opts *opts,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code err_code,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data **e_data)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KRB_ERR_GENERIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_create_edata: creating edata for error %d (%s)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan err_code, error_message(err_code));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(err_code) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_create_td_trusted_certifiers(context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plg_cryptoctx, req_cryptoctx, id_cryptoctx, e_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_create_td_dh_parameters(context, plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_cryptoctx, id_cryptoctx, opts, e_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5KDC_ERR_INVALID_CERTIFICATE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5KDC_ERR_REVOKED_CERTIFICATE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_create_td_invalid_certificate(context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plg_cryptoctx, req_cryptoctx, id_cryptoctx, e_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("no edata needed for error %d (%s)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan err_code, error_message(err_code));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_server_get_edata(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req * request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _krb5_db_entry_new * client,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _krb5_db_entry_new * server,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan preauth_get_entry_data_proc server_get_entry_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *pa_plugin_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data * data)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_context plgctx = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_server_get_edata: entered!\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * If we don't have a realm context for the given realm,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * don't tell the client that we support pkinit!
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx = pkinit_find_realm_context(context, pa_plugin_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan request->server);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanverify_client_san(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_req_context reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal client,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int *valid_san)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal *princs = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal *upns = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_SAN_INFO
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *client_string = NULL, *san_string;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = crypto_retrieve_cert_sans(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, plgctx->idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &princs,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->opts->allow_upn ? &upns : NULL,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: error from retrieve_certificate_sans()\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* XXX Verify this is consistent with client side XXX */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#if 0
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = call_san_checking_plugins(context, plgctx, reqctx, princs,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan upns, NULL, &plugin_decision, &ignore);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: call_san_checking_plugins() returned retval %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: call_san_checking_plugins() returned decision %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, plugin_decision);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plugin_decision != NO_DECISION) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = plugin_decision;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_SAN_INFO
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_unparse_name(context, client, &client_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Checking pkinit sans\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; princs != NULL && princs[i] != NULL; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_SAN_INFO
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_unparse_name(context, princs[i], &san_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Comparing client '%s' to pkinit san value '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, client_string, san_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_unparsed_name(context, san_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_principal_compare(context, princs[i], client)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: pkinit san match found\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *valid_san = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: no pkinit san match found\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * XXX if cert has names but none match, should we
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * be returning KRB5KDC_ERR_CLIENT_NAME_MISMATCH here?
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (upns == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: no upn sans (or we wouldn't accept them anyway)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Checking upn sans\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; upns[i] != NULL; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_SAN_INFO
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_unparse_name(context, upns[i], &san_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Comparing client '%s' to upn san value '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, client_string, san_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_unparsed_name(context, san_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_principal_compare(context, upns[i], client)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: upn san match found\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *valid_san = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: no upn san match found\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* We found no match */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (princs != NULL || upns != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *valid_san = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* XXX ??? If there was one or more name in the cert, but
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * none matched the client name, then return mismatch? */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanout:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (princs != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; princs[i] != NULL; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_principal(context, princs[i]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(princs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (upns != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; upns[i] != NULL; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_principal(context, upns[i]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(upns);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_SAN_INFO
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (client_string != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_unparsed_name(context, client_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning retval %d, valid_san %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, *valid_san);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanverify_client_eku(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_req_context reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int *eku_accepted)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *eku_accepted = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx->opts->require_eku == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: configuration requests no EKU checking\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *eku_accepted = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = crypto_check_cert_eku(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, plgctx->idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0, /* kdc cert */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->opts->accept_secondary_eku,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan eku_accepted);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Error from crypto_check_cert_eku %d (%s)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanout:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning retval %d, eku_accepted %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, *eku_accepted);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_server_verify_padata(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _krb5_db_entry_new * client,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *req_pkt,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req * request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_enc_tkt_part * enc_tkt_reply,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data * data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan preauth_get_entry_data_proc server_get_entry_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *pa_plugin_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void **pa_request_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data **e_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_authdata ***authz_data)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_octet_data authp_data = {0, 0, NULL}, krb5_authz = {0, 0, NULL};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *encoded_pkinit_authz_data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_pk_as_req *reqp = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_pk_as_req_draft9 *reqp9 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_auth_pack *auth_pack = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_auth_pack_draft9 *auth_pack9 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_context plgctx = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_req_context reqctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Solaris Kerberos: set but not used */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#if 0
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_preauthtype pa_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_checksum cksum = {0, 0, 0, NULL};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *der_req = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int valid_eku = 0, valid_san = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_authdata **my_authz_data = NULL, *pkinit_authz_data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req *tmp_as_req = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data k5data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_verify_padata: entered!\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (data == NULL || data->length == 0 || data->contents == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pa_plugin_context == NULL || e_data == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx = pkinit_find_realm_context(context, pa_plugin_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan request->server);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(data->contents, data->length, "/tmp/kdc_as_req");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create a per-request context */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_kdc_req_context(context, (void **)&reqctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->pa_type = data->pa_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PADATA_TO_KRB5DATA(data, &k5data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch ((int)data->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("processing KRB5_PADATA_PK_AS_REQ\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_decode_krb5_pa_pk_as_req(&k5data, &reqp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("decode_krb5_pa_pk_as_req failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(reqp->signedAuthPack.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqp->signedAuthPack.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/kdc_signed_data");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = cms_signeddata_verify(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, plgctx->idctx, CMS_SIGN_CLIENT,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->opts->require_crl_checking,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqp->signedAuthPack.data, reqp->signedAuthPack.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &authp_data.data, &authp_data.length, &krb5_authz.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &krb5_authz.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("processing KRB5_PADATA_PK_AS_REQ_OLD\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_decode_krb5_pa_pk_as_req_draft9(&k5data, &reqp9);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("decode_krb5_pa_pk_as_req_draft9 failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(reqp9->signedAuthPack.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqp9->signedAuthPack.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/kdc_signed_data_draft9");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = cms_signeddata_verify(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, plgctx->idctx, CMS_SIGN_DRAFT9,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->opts->require_crl_checking,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqp9->signedAuthPack.data, reqp9->signedAuthPack.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &authp_data.data, &authp_data.length, &krb5_authz.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &krb5_authz.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("unrecognized pa_type = %d\n", data->pa_type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkcs7_signeddata_verify failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = verify_client_san(context, plgctx, reqctx, request->client,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &valid_san);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!valid_san) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: did not find an acceptable SAN in user certificate\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = verify_client_eku(context, plgctx, reqctx, &valid_eku);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!valid_eku) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: did not find an acceptable EKU in user certificate\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(authp_data.data, authp_data.length, "/tmp/kdc_auth_pack");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan OCTETDATA_TO_KRB5DATA(&authp_data, &k5data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch ((int)data->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_decode_krb5_auth_pack(&k5data, &auth_pack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to decode krb5_auth_pack\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* check dh parameters */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (auth_pack->clientPublicValue != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = server_check_dh(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, plgctx->idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &auth_pack->clientPublicValue->algorithm.parameters,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->opts->dh_min_bits);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("bad dh parameters\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * The KDC may have modified the request after decoding it.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * We need to compute the checksum on the data that
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * came from the client. Therefore, we use the original
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * packet contents.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_decode_krb5_as_req(req_pkt, &tmp_as_req);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("decode_krb5_as_req returned %d\n", (int)retval);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_kdc_req_body(tmp_as_req, &der_req);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("encode_krb5_kdc_req_body returned %d\n", (int) retval);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = krb5_c_make_checksum(context, CKSUMTYPE_NIST_SHA, NULL,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0, der_req, &cksum);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("unable to calculate AS REQ checksum\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cksum.length != auth_pack->pkAuthenticator.paChecksum.length ||
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan memcmp(cksum.contents,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack->pkAuthenticator.paChecksum.contents,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cksum.length)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to match the checksum\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_CKSUM
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("calculating checksum on buf size (%d)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_pkt->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer(req_pkt->data, req_pkt->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("received checksum type=%d size=%d ",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack->pkAuthenticator.paChecksum.checksum_type,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack->pkAuthenticator.paChecksum.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer(auth_pack->pkAuthenticator.paChecksum.contents,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack->pkAuthenticator.paChecksum.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("expected checksum type=%d size=%d ",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cksum.checksum_type, cksum.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer(cksum.contents, cksum.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* check if kdcPkId present and match KDC's subjectIdentifier */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqp->kdcPkId.data != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int valid_kdcPkId = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_check_kdc_pkid(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, plgctx->idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqp->kdcPkId.data, reqp->kdcPkId.length, &valid_kdcPkId);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!valid_kdcPkId)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("kdcPkId in AS_REQ does not match KDC's cert"
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "RFC says to ignore and proceed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* remember the decoded auth_pack for verify_padata routine */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->rcv_auth_pack = auth_pack;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_decode_krb5_auth_pack_draft9(&k5data, &auth_pack9);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to decode krb5_auth_pack_draft9\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (auth_pack9->clientPublicValue != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = server_check_dh(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, plgctx->idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &auth_pack9->clientPublicValue->algorithm.parameters,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->opts->dh_min_bits);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("bad dh parameters\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* remember the decoded auth_pack for verify_padata routine */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->rcv_auth_pack9 = auth_pack9;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack9 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* return authorization data to be included in the ticket */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch ((int)data->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan my_authz_data = malloc(2 * sizeof(*my_authz_data));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (my_authz_data == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Couldn't allocate krb5_authdata ptr array\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan my_authz_data[1] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan my_authz_data[0] = malloc(sizeof(krb5_authdata));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (my_authz_data[0] == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Couldn't allocate krb5_authdata\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(my_authz_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* AD-INITIAL-VERIFIED-CAS must be wrapped in AD-IF-RELEVANT */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan my_authz_data[0]->magic = KV5M_AUTHDATA;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan my_authz_data[0]->ad_type = KRB5_AUTHDATA_IF_RELEVANT;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create an internal AD-INITIAL-VERIFIED-CAS data */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_authz_data = malloc(sizeof(krb5_authdata));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_authz_data == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Couldn't allocate krb5_authdata\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(my_authz_data[0]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(my_authz_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_authz_data->ad_type = KRB5_AUTHDATA_INITIAL_VERIFIED_CAS;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* content of this ad-type contains the certification
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan path with which the client certificate was validated
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_authz_data->contents = krb5_authz.data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_authz_data->length = krb5_authz.length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_authdata_elt(pkinit_authz_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &encoded_pkinit_authz_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)encoded_pkinit_authz_data->data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encoded_pkinit_authz_data->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/kdc_pkinit_authz_data");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(pkinit_authz_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("k5int_encode_krb5_authdata_elt failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(my_authz_data[0]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(my_authz_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan my_authz_data[0]->contents =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_octet *) encoded_pkinit_authz_data->data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan my_authz_data[0]->length = encoded_pkinit_authz_data->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *authz_data = my_authz_data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Returning %d bytes of authorization data\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_authz.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encoded_pkinit_authz_data->data = NULL; /* Don't free during cleanup*/
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(encoded_pkinit_authz_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *authz_data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* remember to set the PREAUTH flag in the reply */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *pa_request_context = reqctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval && data->pa_type == KRB5_PADATA_PK_AS_REQ) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_verify_padata failed: creating e-data\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_create_edata(context, plgctx->cryptoctx, reqctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->idctx, plgctx->opts, retval, e_data))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_create_edata failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch ((int)data->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_pa_pk_as_req(&reqp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cksum.contents != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(cksum.contents);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (der_req != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_data(context, der_req);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_pa_pk_as_req_draft9(&reqp9);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (tmp_as_req != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan k5int_krb5_free_kdc_req(context, tmp_as_req);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (authp_data.data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(authp_data.data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_authz.data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(krb5_authz.data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_kdc_req_context(context, reqctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (auth_pack != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_auth_pack(&auth_pack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (auth_pack9 != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_auth_pack_draft9(context, &auth_pack9);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_server_return_padata(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data * padata,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _krb5_db_entry_new * client,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *req_pkt,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req * request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_rep * reply,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _krb5_key_data * client_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_keyblock * encrypting_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data ** send_pa,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan preauth_get_entry_data_proc server_get_entry_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *pa_plugin_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void **pa_request_context)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data scratch = {0, 0, NULL};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_pk_as_req *reqp = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_pk_as_req_draft9 *reqp9 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *subjectPublicKey = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *dh_pubkey = NULL, *server_key = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int subjectPublicKey_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int server_key_len = 0, dh_pubkey_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_dh_key_info dhkey_info;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *encoded_dhkey_info = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_pk_as_rep *rep = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_pk_as_rep_draft9 *rep9 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *out_data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_enctype enctype = -1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_reply_key_pack *key_pack = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_reply_key_pack_draft9 *key_pack9 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *encoded_key_pack = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int num_types;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cksumtype *cksum_types = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_context plgctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_req_context reqctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int fixed_keypack = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *send_pa = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (padata == NULL || padata->length == 0 || padata->contents == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pa_request_context == NULL || *pa_request_context == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("missing request context \n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx = pkinit_find_realm_context(context, pa_plugin_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan request->server);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Unable to locate correct realm context\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOENT;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_return_padata: entered!\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx = (pkinit_kdc_req_context)*pa_request_context;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (encrypting_key->contents) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(encrypting_key->contents);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encrypting_key->length = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encrypting_key->contents = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for(i = 0; i < request->nktypes; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan enctype = request->ktype[i];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!krb5_c_valid_enctype(enctype))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("KDC picked etype = %d\n", enctype);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (i == request->nktypes) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_ETYPE_NOSUPP;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch((int)reqctx->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan init_krb5_pa_pk_as_rep(&rep);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rep == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* let's assume it's RSA. we'll reset it to DH if needed */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rep->choice = choice_pa_pk_as_rep_encKeyPack;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan init_krb5_pa_pk_as_rep_draft9(&rep9);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rep9 == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rep9->choice = choice_pa_pk_as_rep_draft9_encKeyPack;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->rcv_auth_pack != NULL &&
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->rcv_auth_pack->clientPublicValue != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan subjectPublicKey =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->rcv_auth_pack->clientPublicValue->subjectPublicKey.data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan subjectPublicKey_len =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->rcv_auth_pack->clientPublicValue->subjectPublicKey.length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rep->choice = choice_pa_pk_as_rep_dhInfo;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (reqctx->rcv_auth_pack9 != NULL &&
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->rcv_auth_pack9->clientPublicValue != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan subjectPublicKey =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->rcv_auth_pack9->clientPublicValue->subjectPublicKey.data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan subjectPublicKey_len =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->rcv_auth_pack9->clientPublicValue->subjectPublicKey.length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rep9->choice = choice_pa_pk_as_rep_draft9_dhSignedData;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* if this DH, then process finish computing DH key */
2c2d21e98a95cba5687ec6574c974a5c6c4a6adbRichard Lowe if (((rep != NULL) && (rep->choice == choice_pa_pk_as_rep_dhInfo)) ||
2c2d21e98a95cba5687ec6574c974a5c6c4a6adbRichard Lowe ((rep9 != NULL) && rep9->choice ==
2c2d21e98a95cba5687ec6574c974a5c6c4a6adbRichard Lowe choice_pa_pk_as_rep_draft9_dhSignedData)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("received DH key delivery AS REQ\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = server_process_dh(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, plgctx->idctx, subjectPublicKey,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan subjectPublicKey_len, &dh_pubkey, &dh_pubkey_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &server_key, &server_key_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to process/create dh paramters\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((rep9 != NULL &&
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rep9->choice == choice_pa_pk_as_rep_draft9_dhSignedData) ||
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (rep != NULL && rep->choice == choice_pa_pk_as_rep_dhInfo)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_octetstring2key(context, enctype, server_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan server_key_len, encrypting_key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_octetstring2key failed: %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dhkey_info.subjectPublicKey.length = dh_pubkey_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dhkey_info.subjectPublicKey.data = dh_pubkey;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dhkey_info.nonce = request->nonce;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dhkey_info.dhKeyExpiration = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_kdc_dh_key_info(&dhkey_info,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &encoded_dhkey_info);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("encode_krb5_kdc_dh_key_info failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)encoded_dhkey_info->data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encoded_dhkey_info->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/kdc_dh_key_info");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch ((int)padata->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = cms_signeddata_create(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, plgctx->idctx, CMS_SIGN_SERVER, 1,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned char *)encoded_dhkey_info->data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encoded_dhkey_info->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &rep->u.dh_Info.dhSignedData.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &rep->u.dh_Info.dhSignedData.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to create pkcs7 signed data\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = cms_signeddata_create(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, plgctx->idctx, CMS_SIGN_DRAFT9, 1,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned char *)encoded_dhkey_info->data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encoded_dhkey_info->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &rep9->u.dhSignedData.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &rep9->u.dhSignedData.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to create pkcs7 signed data\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("received RSA key delivery AS REQ\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = krb5_c_make_random_key(context, enctype, encrypting_key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("unable to make a session key\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* check if PA_TYPE of 132 is present which means the client is
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * requesting that a checksum is send back instead of the nonce
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; request->padata[i] != NULL; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Checking pa_type 0x%08x\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, request->padata[i]->pa_type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (request->padata[i]->pa_type == 132)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan fixed_keypack = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: return checksum instead of nonce = %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, fixed_keypack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* if this is an RFC reply or draft9 client requested a checksum
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * in the reply instead of the nonce, create an RFC-style keypack
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((int)padata->pa_type == KRB5_PADATA_PK_AS_REQ || fixed_keypack) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan init_krb5_reply_key_pack(&key_pack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (key_pack == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* retrieve checksums for a given enctype of the reply key */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = krb5_c_keyed_checksum_types(context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encrypting_key->enctype, &num_types, &cksum_types);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* pick the first of acceptable enctypes for the checksum */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = krb5_c_make_checksum(context, cksum_types[0],
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encrypting_key, KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_pkt, &key_pack->asChecksum);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("unable to calculate AS REQ checksum\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_CKSUM
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("calculating checksum on buf size = %d\n", req_pkt->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer(req_pkt->data, req_pkt->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("checksum size = %d\n", key_pack->asChecksum.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer(key_pack->asChecksum.contents,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_pack->asChecksum.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("encrypting key (%d)\n", encrypting_key->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer(encrypting_key->contents, encrypting_key->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_copy_keyblock_contents(context, encrypting_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &key_pack->replyKey);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_reply_key_pack(key_pack,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &encoded_key_pack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to encode reply_key_pack\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch ((int)padata->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rep->choice = choice_pa_pk_as_rep_encKeyPack;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = cms_envelopeddata_create(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, plgctx->idctx, padata->pa_type, 1,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned char *)encoded_key_pack->data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encoded_key_pack->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &rep->u.encKeyPack.data, &rep->u.encKeyPack.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* if the request is from the broken draft9 client that
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * expects back a nonce, create it now
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!fixed_keypack) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan init_krb5_reply_key_pack_draft9(&key_pack9);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (key_pack9 == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_pack9->nonce = reqctx->rcv_auth_pack9->pkAuthenticator.nonce;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_copy_keyblock_contents(context, encrypting_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &key_pack9->replyKey);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_reply_key_pack_draft9(key_pack9,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &encoded_key_pack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to encode reply_key_pack\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rep9->choice = choice_pa_pk_as_rep_draft9_encKeyPack;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = cms_envelopeddata_create(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, plgctx->idctx, padata->pa_type, 1,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned char *)encoded_key_pack->data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encoded_key_pack->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &rep9->u.encKeyPack.data, &rep9->u.encKeyPack.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to create pkcs7 enveloped data: %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)encoded_key_pack->data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encoded_key_pack->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/kdc_key_pack");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch ((int)padata->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(rep->u.encKeyPack.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rep->u.encKeyPack.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/kdc_enc_key_pack");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(rep9->u.encKeyPack.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rep9->u.encKeyPack.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/kdc_enc_key_pack");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch ((int)padata->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_pa_pk_as_rep(rep, &out_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_pa_pk_as_rep_draft9(rep9, &out_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to encode AS_REP\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (out_data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)out_data->data, out_data->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/kdc_as_rep");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *send_pa = (krb5_pa_data *) malloc(sizeof(krb5_pa_data));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (*send_pa == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(out_data->data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(out_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan out_data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*send_pa)->magic = KV5M_PA_DATA;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch ((int)padata->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*send_pa)->pa_type = KRB5_PADATA_PK_AS_REP;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*send_pa)->pa_type = KRB5_PADATA_PK_AS_REP_OLD;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*send_pa)->length = out_data->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*send_pa)->contents = (krb5_octet *) out_data->data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_kdc_req_context(context, reqctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (scratch.data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(scratch.data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (out_data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(out_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (encoded_dhkey_info != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_data(context, encoded_dhkey_info);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (encoded_key_pack != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_data(context, encoded_key_pack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dh_pubkey != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(dh_pubkey);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (server_key != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(server_key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cksum_types != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(cksum_types);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch ((int)padata->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_pa_pk_as_req(&reqp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_pa_pk_as_rep(&rep);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_reply_key_pack(&key_pack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_pa_pk_as_req_draft9(&reqp9);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_pa_pk_as_rep_draft9(&rep9);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!fixed_keypack)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_reply_key_pack_draft9(&key_pack9);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_reply_key_pack(&key_pack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_verify_padata failure");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_server_get_flags(krb5_context kcontext, krb5_preauthtype patype)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return PA_SUFFICIENT | PA_REPLACES_KEY;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_preauthtype supported_server_pa_types[] = {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan KRB5_PADATA_PK_AS_REQ,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan KRB5_PADATA_PK_AS_REQ_OLD,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan KRB5_PADATA_PK_AS_REP_OLD,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_kdc_profile(krb5_context context, pkinit_kdc_context plgctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * There is nothing currently allocated by pkinit_init_kdc_profile()
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * which needs to be freed here.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_kdc_profile(krb5_context context, pkinit_kdc_context plgctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *eku_string = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: entered for realm %s\n", __FUNCTION__, plgctx->realmname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_kdcdefault_string(context, plgctx->realmname,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_identity",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &plgctx->idopts->identity);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval != 0 || NULL == plgctx->idopts->identity) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "No pkinit_identity supplied for realm %s",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->realmname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_kdcdefault_strings(context, plgctx->realmname,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_anchors",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &plgctx->idopts->anchors);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval != 0 || NULL == plgctx->idopts->anchors) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "No pkinit_anchors supplied for realm %s",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->realmname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_kdcdefault_strings(context, plgctx->realmname,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_pool",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &plgctx->idopts->intermediates);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_kdcdefault_strings(context, plgctx->realmname,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_revoke",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &plgctx->idopts->crls);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_kdcdefault_string(context, plgctx->realmname,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_kdc_ocsp",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &plgctx->idopts->ocsp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_kdcdefault_string(context, plgctx->realmname,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_mappings_file",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &plgctx->idopts->dn_mapping_file);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_kdcdefault_integer(context, plgctx->realmname,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_dh_min_bits",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKINIT_DEFAULT_DH_MIN_BITS,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &plgctx->opts->dh_min_bits);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx->opts->dh_min_bits < 1024) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: invalid value (%d) for pkinit_dh_min_bits, "
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "using default value (%d) instead\n", __FUNCTION__,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->opts->dh_min_bits, PKINIT_DEFAULT_DH_MIN_BITS);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->opts->dh_min_bits = PKINIT_DEFAULT_DH_MIN_BITS;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_kdcdefault_boolean(context, plgctx->realmname,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_allow_upn",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0, &plgctx->opts->allow_upn);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_kdcdefault_boolean(context, plgctx->realmname,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_require_crl_checking",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0, &plgctx->opts->require_crl_checking);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_kdcdefault_string(context, plgctx->realmname,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_eku_checking",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &eku_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (eku_string != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (strcasecmp(eku_string, "kpClientAuth") == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->opts->require_eku = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->opts->accept_secondary_eku = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (strcasecmp(eku_string, "scLogin") == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->opts->require_eku = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->opts->accept_secondary_eku = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (strcasecmp(eku_string, "none") == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->opts->require_eku = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->opts->accept_secondary_eku = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Invalid value for pkinit_eku_checking: '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, eku_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(eku_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanerrout:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_kdc_profile(context, plgctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic pkinit_kdc_context
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_find_realm_context(krb5_context context, void *pa_plugin_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal princ)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_context *realm_contexts = pa_plugin_context;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pa_plugin_context == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; realm_contexts[i] != NULL; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_context p = realm_contexts[i];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p->realmname_len == princ->realm.length) &&
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (strncmp(p->realmname, princ->realm.data, p->realmname_len) == 0)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning context at %p for realm '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, p, p->realmname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return p;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: unable to find realm context for realm '%.*s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, princ->realm.length, princ->realm.data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_server_plugin_init_realm(krb5_context context, const char *realmname,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_context *pplgctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_context plgctx = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *pplgctx = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx = (pkinit_kdc_context) calloc(1, sizeof(*plgctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: initializing context at %p for realm '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, plgctx, realmname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memset(plgctx, 0, sizeof(*plgctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->magic = PKINIT_CTX_MAGIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->realmname = strdup(realmname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx->realmname == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->realmname_len = strlen(plgctx->realmname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_plg_crypto(&plgctx->cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_plg_opts(&plgctx->opts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_identity_crypto(&plgctx->idctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_identity_opts(&plgctx->idopts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_kdc_profile(context, plgctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Solaris Kerberos:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Some methods of storing key information (PKCS11, PKCS12,...) may
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * require interactive prompting.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_identity_set_prompter(plgctx->idctx, krb5_prompter_posix,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_identity_initialize(context, plgctx->cryptoctx, NULL,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->idopts, plgctx->idctx, 0, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning context at %p for realm '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, plgctx, realmname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *pplgctx = plgctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanerrout:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_server_plugin_fini_realm(context, plgctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_server_plugin_init(krb5_context context, void **blob,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const char **realmnames)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_context plgctx, *realm_contexts = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i, j;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size_t numrealms;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_accessor_init();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Determine how many realms we may need to support */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; realmnames[i] != NULL; i++) {};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan numrealms = i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan realm_contexts = (pkinit_kdc_context *)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan calloc(numrealms+1, sizeof(pkinit_kdc_context));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (realm_contexts == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0, j = 0; i < numrealms; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: processing realm '%s'\n", __FUNCTION__, realmnames[i]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_server_plugin_init_realm(context, realmnames[i], &plgctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval == 0 && plgctx != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan realm_contexts[j++] = plgctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (j == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Solaris Kerberos
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Improve error messages for the common case of a single realm
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (numrealms != 1) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "No realms configured "
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "correctly for pkinit support");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *blob = realm_contexts;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning context at %p\n", __FUNCTION__, realm_contexts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanerrout:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_server_plugin_fini(context, realm_contexts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_server_plugin_fini_realm(krb5_context context, pkinit_kdc_context plgctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_kdc_profile(context, plgctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_identity_opts(plgctx->idopts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_identity_crypto(plgctx->idctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_plg_crypto(plgctx->cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_plg_opts(plgctx->opts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(plgctx->realmname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(plgctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_server_plugin_fini(krb5_context context, void *blob)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_context *realm_contexts = blob;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (realm_contexts == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; realm_contexts[i] != NULL; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_server_plugin_fini_realm(context, realm_contexts[i]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: freeing context at %p\n", __FUNCTION__, realm_contexts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(realm_contexts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_kdc_req_context(krb5_context context, void **ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_req_context reqctx = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx = (pkinit_kdc_req_context)malloc(sizeof(*reqctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memset(reqctx, 0, sizeof(*reqctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->magic = PKINIT_CTX_MAGIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_req_crypto(&reqctx->cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->rcv_auth_pack = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->rcv_auth_pack9 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning reqctx at %p\n", __FUNCTION__, reqctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ctx = reqctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_kdc_req_context(context, reqctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_kdc_req_context(krb5_context context, void *ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_kdc_req_context reqctx = (pkinit_kdc_req_context)ctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx == NULL || reqctx->magic != PKINIT_CTX_MAGIC) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_fini_kdc_req_context: got bad reqctx (%p)!\n", reqctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: freeing reqctx at %p\n", __FUNCTION__, reqctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_req_crypto(reqctx->cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->rcv_auth_pack != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_auth_pack(&reqctx->rcv_auth_pack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->rcv_auth_pack9 != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_auth_pack_draft9(context, &reqctx->rcv_auth_pack9);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(reqctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstruct krb5plugin_preauth_server_ftable_v1 preauthentication_server_1 = {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit", /* name */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan supported_server_pa_types, /* pa_type_list */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_server_plugin_init, /* (*init_proc) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_server_plugin_fini, /* (*fini_proc) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_server_get_flags, /* (*flags_proc) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_server_get_edata, /* (*edata_proc) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_server_verify_padata,/* (*verify_proc) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_server_return_padata,/* (*return_proc) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL, /* (*freepa_reqcontext_proc) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan};