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
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash/*
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash */
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <stdio.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <stdlib.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <errno.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <unistd.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <string.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <ctype.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <assert.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <dlfcn.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <sys/stat.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include "pkinit.h"
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef LONGHORN_BETA_COMPAT
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * It is anticipated that all the special checks currently
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * required when talking to a Longhorn server will go away
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * by the time it is officially released and all references
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * to the longhorn global can be removed and any code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * #ifdef'd with LONGHORN_BETA_COMPAT can be removed.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Current testing (20070620) is against a patched Beta 3
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * version of Longhorn. Most, if not all, problems should
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * be fixed in SP1 of Longhorn.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanint longhorn = 0; /* Talking to a Longhorn server? */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code pkinit_client_process
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context context, void *plugin_context, void *request_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_get_init_creds_opt *gic_opt,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan preauth_get_client_data_proc get_data_proc,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _krb5_preauth_client_rock *rock,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req * request, krb5_data *encoded_request_body,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *encoded_previous_request, krb5_pa_data *in_padata,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_prompter_fct prompter, void *prompter_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan preauth_get_as_key_proc gak_fct, void *gak_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data * salt, krb5_data * s2kparams,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_keyblock * as_key, krb5_pa_data *** out_padata);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code pkinit_client_tryagain
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context context, void *plugin_context, void *request_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_get_init_creds_opt *gic_opt,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan preauth_get_client_data_proc get_data_proc,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _krb5_preauth_client_rock *rock,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req * request, krb5_data *encoded_request_body,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *encoded_previous_request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data *in_padata, krb5_error *err_reply,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_prompter_fct prompter, void *prompter_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan preauth_get_as_key_proc gak_fct, void *gak_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data * salt, krb5_data * s2kparams,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_keyblock * as_key, krb5_pa_data *** out_padata);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanvoid pkinit_client_req_init
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context contex, void *plugin_context, void **request_context);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanvoid pkinit_client_req_fini
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context context, void *plugin_context, void *request_context);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code pa_pkinit_gen_req
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context context, pkinit_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_context reqctx, krb5_kdc_req * request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data * in_padata, krb5_pa_data *** out_padata,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_prompter_fct prompter, void *prompter_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_get_init_creds_opt *gic_opt);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code pkinit_as_req_create
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context context, pkinit_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_context reqctx, krb5_timestamp ctsec,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_int32 cusec, krb5_ui_4 nonce,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const krb5_checksum * cksum, krb5_principal server,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data ** as_req);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code pkinit_as_rep_parse
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context context, pkinit_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_context reqctx, krb5_preauthtype pa_type,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req * request, const krb5_data * as_rep,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_keyblock * key_block, krb5_enctype etype, krb5_data *);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code pa_pkinit_parse_rep
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (krb5_context context, pkinit_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_context reqcxt, krb5_kdc_req * request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data * in_padata, krb5_enctype etype,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_keyblock * as_key, krb5_data *);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int pkinit_client_plugin_init(krb5_context context, void **blob);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void pkinit_client_plugin_fini(krb5_context context, void *blob);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpa_pkinit_gen_req(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_context reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req * request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data * in_padata,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data *** out_padata,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_prompter_fct prompter,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *prompter_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_get_init_creds_opt *gic_opt)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *out_data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_timestamp ctsec = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_int32 cusec = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_ui_4 nonce = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_checksum cksum;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *der_req = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data **return_pa_data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cksum.contents = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->pa_type = in_padata->pa_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("kdc_options = 0x%x till = %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan request->kdc_options, request->till);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* If we don't have a client, we're done */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (request->client == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("No request->client; aborting PKINIT\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_get_kdc_cert(context, plgctx->cryptoctx, reqctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->idctx, request->server);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_get_kdc_cert returned %d\n", retval);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* checksum of the encoded KDC-REQ-BODY */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_kdc_req_body(request, &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
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = krb5_c_make_checksum(context, CKSUMTYPE_NIST_SHA, NULL, 0,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan der_req, &cksum);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_CKSUM
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("calculating checksum on buf size (%d)\n", der_req->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer(der_req->data, der_req->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = krb5_us_timeofday(context, &ctsec, &cusec);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* XXX PKINIT RFC says that nonce in PKAuthenticator doesn't have be the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * same as in the AS_REQ. However, if we pick a different nonce, then we
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * need to remember that info when AS_REP is returned. I'm choosing to
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * reuse the AS_REQ nonce.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nonce = request->nonce;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_as_req_create(context, plgctx, reqctx, ctsec, cusec,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nonce, &cksum, request->server, &out_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval || !out_data->length) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("error %d on pkinit_as_req_create; aborting PKINIT\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int) retval);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * The most we'll return is two pa_data, normally just one.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * We need to make room for the NULL terminator.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return_pa_data = (krb5_pa_data **) malloc(3 * sizeof(krb5_pa_data *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (return_pa_data == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return_pa_data[1] = NULL; /* in case of an early trip to cleanup */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return_pa_data[2] = NULL; /* Terminate the list */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return_pa_data[0] = (krb5_pa_data *) malloc(sizeof(krb5_pa_data));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (return_pa_data[0] == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return_pa_data[1] = (krb5_pa_data *) malloc(sizeof(krb5_pa_data));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (return_pa_data[1] == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return_pa_data[0]->magic = KV5M_PA_DATA;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (in_padata->pa_type == KRB5_PADATA_PK_AS_REQ_OLD)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return_pa_data[0]->pa_type = KRB5_PADATA_PK_AS_REP_OLD;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return_pa_data[0]->pa_type = in_padata->pa_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return_pa_data[0]->length = out_data->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return_pa_data[0]->contents = (krb5_octet *) out_data->data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef LONGHORN_BETA_COMPAT
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * LH Beta 3 requires the extra pa-data, even for RFC requests,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * in order to get the Checksum rather than a Nonce in the reply.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * This can be removed when LH SP1 is released.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((return_pa_data[0]->pa_type == KRB5_PADATA_PK_AS_REP_OLD
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan && reqctx->opts->win2k_require_cksum) || (longhorn == 1)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((return_pa_data[0]->pa_type == KRB5_PADATA_PK_AS_REP_OLD
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan && reqctx->opts->win2k_require_cksum)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return_pa_data[1]->pa_type = 132;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return_pa_data[1]->length = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return_pa_data[1]->contents = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(return_pa_data[1]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return_pa_data[1] = NULL; /* Move the list terminator */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_padata = return_pa_data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (der_req != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_data(context, der_req);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (out_data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(out_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (return_pa_data) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (return_pa_data[0] != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(return_pa_data[0]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (return_pa_data[1] != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(return_pa_data[1]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(return_pa_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (out_data) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(out_data->data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(out_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_as_req_create(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_context reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_timestamp ctsec,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_int32 cusec,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_ui_4 nonce,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const krb5_checksum * cksum,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal server,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data ** as_req)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_subject_pk_info *info = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *coded_auth_pack = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_auth_pack *auth_pack = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_pk_as_req *req = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_auth_pack_draft9 *auth_pack9 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_pk_as_req_draft9 *req9 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int protocol = reqctx->opts->dh_or_rsa;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_as_req_create pa_type = %d\n", reqctx->pa_type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Create the authpack */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch((int)reqctx->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan protocol = RSA_PROTOCOL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan init_krb5_auth_pack_draft9(&auth_pack9);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (auth_pack9 == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack9->pkAuthenticator.ctime = ctsec;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack9->pkAuthenticator.cusec = cusec;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack9->pkAuthenticator.nonce = nonce;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack9->pkAuthenticator.kdcName = server;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack9->pkAuthenticator.kdcRealm.magic = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack9->pkAuthenticator.kdcRealm.data =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned char *)server->realm.data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack9->pkAuthenticator.kdcRealm.length = server->realm.length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(cksum->contents);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan init_krb5_subject_pk_info(&info);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (info == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan init_krb5_auth_pack(&auth_pack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (auth_pack == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack->pkAuthenticator.ctime = ctsec;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack->pkAuthenticator.cusec = cusec;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack->pkAuthenticator.nonce = nonce;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack->pkAuthenticator.paChecksum = *cksum;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack->clientDHNonce.length = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack->clientPublicValue = info;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* add List of CMS algorithms */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = create_krb5_supportedCMSTypes(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, reqctx->idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &auth_pack->supportedCMSTypes);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("as_req: unrecognized pa_type = %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int)reqctx->pa_type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = -1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(protocol) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case DH_PROTOCOL:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("as_req: DH key transport algorithm\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_copy_krb5_octet_data(&info->algorithm.algorithm, &dh_oid);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to copy dh_oid\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create client-side DH keys */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((retval = client_create_dh(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, reqctx->idctx, reqctx->opts->dh_size,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &info->algorithm.parameters.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &info->algorithm.parameters.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &info->subjectPublicKey.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &info->subjectPublicKey.length)) != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to create dh parameters\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case RSA_PROTOCOL:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("as_req: RSA key transport algorithm\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch((int)reqctx->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack9->clientPublicValue = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_subject_pk_info(&info);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan auth_pack->clientPublicValue = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("as_req: unknown key transport protocol %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan protocol);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = -1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Encode the authpack */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch((int)reqctx->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_auth_pack(auth_pack, &coded_auth_pack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_auth_pack_draft9(auth_pack9,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &coded_auth_pack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to encode the AuthPack %d\n", retval);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)coded_auth_pack->data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan coded_auth_pack->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/client_auth_pack");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create PKCS7 object from authpack */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch((int)reqctx->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan init_krb5_pa_pk_as_req(&req);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (req == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = cms_signeddata_create(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, reqctx->idctx, CMS_SIGN_CLIENT, 1,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned char *)coded_auth_pack->data, coded_auth_pack->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &req->signedAuthPack.data, &req->signedAuthPack.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)req->signedAuthPack.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req->signedAuthPack.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/client_signed_data");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan init_krb5_pa_pk_as_req_draft9(&req9);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (req9 == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = cms_signeddata_create(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, reqctx->idctx, CMS_SIGN_DRAFT9, 1,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned char *)coded_auth_pack->data, coded_auth_pack->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &req9->signedAuthPack.data, &req9->signedAuthPack.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)req9->signedAuthPack.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req9->signedAuthPack.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/client_signed_data_draft9");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_data(context, coded_auth_pack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to create pkcs7 signed data\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create a list of trusted CAs */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch((int)reqctx->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = create_krb5_trustedCertifiers(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, reqctx->idctx, &req->trustedCertifiers);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = create_issuerAndSerial(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, reqctx->idctx, &req->kdcPkId.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &req->kdcPkId.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Encode the as-req */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_pa_pk_as_req(req, as_req);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#if 0
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* W2K3 KDC doesn't like this */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = create_krb5_trustedCas(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, reqctx->idctx, 1, &req9->trustedCertifiers);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = create_issuerAndSerial(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, reqctx->idctx, &req9->kdcCert.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &req9->kdcCert.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Encode the as-req */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_pa_pk_as_req_draft9(req9, as_req);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)(*as_req)->data, (*as_req)->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/client_as_req");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch((int)reqctx->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_auth_pack(&auth_pack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_pa_pk_as_req(&req);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_pa_pk_as_req_draft9(&req9);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(auth_pack9);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_as_req_create retval=%d\n", (int) retval);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpa_pkinit_parse_rep(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_context reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req * request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data * in_padata,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_enctype etype,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_keyblock * as_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *encoded_request)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data asRep = { 0, 0, NULL};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * One way or the other - success or failure - no other PA systems can
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * work if the server sent us a PKINIT reply, since only we know how to
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * decrypt the key.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((in_padata == NULL) || (in_padata->length == 0)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pa_pkinit_parse_rep: no in_padata\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan asRep.data = (char *) in_padata->contents;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan asRep.length = in_padata->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_as_rep_parse(context, plgctx, reqctx, in_padata->pa_type,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan request, &asRep, as_key, etype, encoded_request);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_as_rep_parse returned %d (%s)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanverify_kdc_san(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_context reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal kdcprinc,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int *valid_san,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int *need_eku_checking)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char **certhosts = NULL, **cfghosts = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal *princs = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char ***get_dns;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i, j;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *valid_san = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *need_eku_checking = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_libdefault_strings(context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_princ_realm(context, kdcprinc),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_kdc_hostname",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &cfghosts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval || cfghosts == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: No pkinit_kdc_hostname values found in config file\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan get_dns = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: pkinit_kdc_hostname values found in config file\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan get_dns = (unsigned char ***)&certhosts;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = crypto_retrieve_cert_sans(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, reqctx->idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &princs, NULL, get_dns);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: error from retrieve_certificate_sans()\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_KDC_NAME_MISMATCH;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#if 0
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = call_san_checking_plugins(context, plgctx, reqctx, idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan princs, hosts, &plugin_decision,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan need_eku_checking);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: call_san_checking_plugins() returned retval %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_KDC_NAME_MISMATCH;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: call_san_checking_plugins() returned decision %d and "
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "need_eku_checking %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, plugin_decision, *need_eku_checking);
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 pkiDebug("%s: Checking pkinit sans\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; princs != NULL && princs[i] != NULL; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_principal_compare(context, princs[i], kdcprinc)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: pkinit san match found\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *valid_san = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *need_eku_checking = 0;
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 if (certhosts == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: no certhosts (or we wouldn't accept them anyway)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_KDC_NAME_MISMATCH;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; certhosts[i] != NULL; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (j = 0; cfghosts != NULL && cfghosts[j] != NULL; j++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: comparing cert name '%s' with config name '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, certhosts[i], cfghosts[j]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (strcmp(certhosts[i], cfghosts[j]) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: we have a dnsName match\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *valid_san = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: no dnsName san match found\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* We found no match */
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 (certhosts != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; certhosts[i] != NULL; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(certhosts[i]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(certhosts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cfghosts != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan profile_free_list(cfghosts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning retval %d, valid_san %d, need_eku_checking %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, *valid_san, *need_eku_checking);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanverify_kdc_eku(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_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 (reqctx->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 retval = crypto_check_cert_eku(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, reqctx->idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 1, /* kdc cert */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->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/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Parse PA-PK-AS-REP message. Optionally evaluates the message's
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * certificate chain.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Optionally returns various components.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_as_rep_parse(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_context reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_preauthtype pa_type,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req *request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const krb5_data *as_rep,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_keyblock *key_block,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_enctype etype,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *encoded_request)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_pk_as_rep *kdc_reply = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_dh_key_info *kdc_dh = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_reply_key_pack *key_pack = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_reply_key_pack_draft9 *key_pack9 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_octet_data dh_data = { 0, 0, NULL };
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *client_key = NULL, *kdc_hostname = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int client_key_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_checksum cksum = {0, 0, 0, NULL};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data k5data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int valid_san = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int valid_eku = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int need_eku_checking = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan assert((as_rep != NULL) && (key_block != NULL));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)as_rep->data, as_rep->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/client_as_rep");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((retval = k5int_decode_krb5_pa_pk_as_rep(as_rep, &kdc_reply))) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("decode_krb5_as_rep failed %d\n", retval);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(kdc_reply->choice) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case choice_pa_pk_as_rep_dhInfo:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("as_rep: DH key transport algorithm\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(kdc_reply->u.dh_Info.dhSignedData.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kdc_reply->u.dh_Info.dhSignedData.length, "/tmp/client_kdc_signeddata");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((retval = cms_signeddata_verify(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, reqctx->idctx, CMS_SIGN_SERVER,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->require_crl_checking,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kdc_reply->u.dh_Info.dhSignedData.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kdc_reply->u.dh_Info.dhSignedData.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &dh_data.data, &dh_data.length, NULL, NULL)) != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to verify pkcs7 signed data\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case choice_pa_pk_as_rep_encKeyPack:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("as_rep: RSA key transport algorithm\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((retval = cms_envelopeddata_verify(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, reqctx->idctx, pa_type,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->require_crl_checking,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kdc_reply->u.encKeyPack.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kdc_reply->u.encKeyPack.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &dh_data.data, &dh_data.length)) != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to verify pkcs7 enveloped data\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("unknown as_rep type %d\n", kdc_reply->choice);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = -1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = verify_kdc_san(context, plgctx, reqctx, request->server,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &valid_san, &need_eku_checking);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!valid_san) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: did not find an acceptable SAN in KDC certificate\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_KDC_NAME_MISMATCH;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (need_eku_checking) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = verify_kdc_eku(context, plgctx, reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &valid_eku);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!valid_eku) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: did not find an acceptable EKU in KDC certificate\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: skipping EKU check\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan OCTETDATA_TO_KRB5DATA(&dh_data, &k5data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(kdc_reply->choice) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case choice_pa_pk_as_rep_dhInfo:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(dh_data.data, dh_data.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/client_dh_key");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((retval = k5int_decode_krb5_kdc_dh_key_info(&k5data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &kdc_dh)) != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to decode kdc_dh_key_info\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* client after KDC reply */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((retval = client_process_dh(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, reqctx->idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kdc_dh->subjectPublicKey.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kdc_dh->subjectPublicKey.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &client_key, &client_key_len)) != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to process dh params\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_octetstring2key(context, etype, client_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan client_key_len, key_block);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to create key pkinit_octetstring2key %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case choice_pa_pk_as_rep_encKeyPack:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(dh_data.data, dh_data.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/client_key_pack");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((retval = k5int_decode_krb5_reply_key_pack(&k5data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &key_pack)) != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to decode reply_key_pack\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef LONGHORN_BETA_COMPAT
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * LH Beta 3 requires the extra pa-data, even for RFC requests,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * in order to get the Checksum rather than a Nonce in the reply.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * This can be removed when LH SP1 is released.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pa_type == KRB5_PADATA_PK_AS_REP && longhorn == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pa_type == KRB5_PADATA_PK_AS_REP)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((retval =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan k5int_decode_krb5_reply_key_pack_draft9(&k5data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &key_pack9)) != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to decode reply_key_pack_draft9\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("decode reply_key_pack_draft9\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (key_pack9->nonce != request->nonce) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("nonce in AS_REP=%d doesn't match AS_REQ=%d\n", key_pack9->nonce, request->nonce);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = -1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_copy_keyblock_contents(context, &key_pack9->replyKey,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_block);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * This is hack but Windows sends back SHA1 checksum
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * with checksum type of 14. There is currently no
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * checksum type of 14 defined.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (key_pack->asChecksum.checksum_type == 14)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_pack->asChecksum.checksum_type = CKSUMTYPE_NIST_SHA;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = krb5_c_make_checksum(context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_pack->asChecksum.checksum_type,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &key_pack->replyKey,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encoded_request, &cksum);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to make a checksum\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((cksum.length != key_pack->asChecksum.length) ||
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan memcmp(cksum.contents, key_pack->asChecksum.contents,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cksum.length)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to match the checksums\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_CKSUM
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("calculating checksum on buf size (%d)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encoded_request->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer(encoded_request->data, encoded_request->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("encrypting key (%d)\n", key_pack->replyKey.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer(key_pack->replyKey.contents,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_pack->replyKey.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("received checksum type=%d size=%d ",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_pack->asChecksum.checksum_type,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_pack->asChecksum.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer(key_pack->asChecksum.contents,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_pack->asChecksum.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 goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("checksums match\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_copy_keyblock_contents(context, &key_pack->replyKey,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_block);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("unknow as_rep type %d\n", kdc_reply->choice);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dh_data.data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(dh_data.data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (client_key != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(client_key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_kdc_dh_key_info(&kdc_dh);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_pa_pk_as_rep(&kdc_reply);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (key_pack != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_reply_key_pack(&key_pack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cksum.contents != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(cksum.contents);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (key_pack9 != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_reply_key_pack_draft9(&key_pack9);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (kdc_hostname != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(kdc_hostname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_as_rep_parse returning %d (%s)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_client_profile(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_context reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req *request)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *eku_string = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_client_profile %p %p %p %p\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan context, plgctx, reqctx, request);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_libdefault_boolean(context, &request->server->realm,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_win2k",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->win2k_target,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &reqctx->opts->win2k_target);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_libdefault_boolean(context, &request->server->realm,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_win2k_require_binding",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->win2k_require_cksum,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &reqctx->opts->win2k_require_cksum);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_libdefault_boolean(context, &request->server->realm,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_require_crl_checking",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->require_crl_checking,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &reqctx->opts->require_crl_checking);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_libdefault_integer(context, &request->server->realm,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_dh_min_bits",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->dh_size,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &reqctx->opts->dh_size);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->opts->dh_size != 1024 && reqctx->opts->dh_size != 2048
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan && reqctx->opts->dh_size != 4096) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: invalid value (%d) for pkinit_dh_min_bits, "
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "using default value (%d) instead\n", __FUNCTION__,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->dh_size, PKINIT_DEFAULT_DH_MIN_BITS);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->dh_size = PKINIT_DEFAULT_DH_MIN_BITS;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_libdefault_string(context, &request->server->realm,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_eku_checking",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &eku_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (eku_string != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (strcasecmp(eku_string, "kpKDC") == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->require_eku = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->accept_secondary_eku = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (strcasecmp(eku_string, "kpServerAuth") == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->require_eku = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->accept_secondary_eku = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (strcasecmp(eku_string, "none") == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->require_eku = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->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#ifdef LONGHORN_BETA_COMPAT
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Temporarily just set global flag from config file */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_libdefault_boolean(context, &request->server->realm,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_longhorn",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &longhorn);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Only process anchors here if they were not specified on command line */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->idopts->anchors == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_libdefault_strings(context, &request->server->realm,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_anchors",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &reqctx->idopts->anchors);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_libdefault_strings(context, &request->server->realm,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_pool",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &reqctx->idopts->intermediates);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_libdefault_strings(context, &request->server->realm,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_revoke",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &reqctx->idopts->crls);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) pkinit_libdefault_strings(context, &request->server->realm,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit_identities",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &reqctx->idopts->identity_alt);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_client_process(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *plugin_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *request_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_get_init_creds_opt *gic_opt,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan preauth_get_client_data_proc get_data_proc,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _krb5_preauth_client_rock *rock,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req *request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *encoded_request_body,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *encoded_previous_request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data *in_padata,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_prompter_fct prompter,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *prompter_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan preauth_get_as_key_proc gak_fct,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *gak_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *salt,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *s2kparams,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_keyblock *as_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data ***out_padata)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_enctype enctype = -1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *cdata = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int processing_request = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_context plgctx = (pkinit_context)plugin_context;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_context reqctx = (pkinit_req_context)request_context;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_client_process %p %p %p %p\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan context, plgctx, reqctx, request);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx == NULL || reqctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch ((int) in_padata->pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("processing KRB5_PADATA_PK_AS_REQ\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan processing_request = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("processing KRB5_PADATA_PK_AS_REP\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (in_padata->length == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("processing KRB5_PADATA_PK_AS_REQ_OLD\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan in_padata->pa_type = KRB5_PADATA_PK_AS_REQ_OLD;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan processing_request = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("processing KRB5_PADATA_PK_AS_REP_OLD\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan in_padata->pa_type = KRB5_PADATA_PK_AS_REP_OLD;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("unrecognized patype = %d for PKINIT\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan in_padata->pa_type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (processing_request) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_client_profile(context, plgctx, reqctx, request);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_identity_set_prompter(reqctx->idctx, prompter, prompter_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_identity_set_prompter returned %d (%s)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_identity_initialize(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, reqctx->idopts,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->idctx, 1, request->client);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_identity_initialize returned %d (%s)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pa_pkinit_gen_req(context, plgctx, reqctx, request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan in_padata, out_padata, prompter,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan prompter_data, gic_opt);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Get the enctype of the reply.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = (*get_data_proc)(context, rock,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5plugin_preauth_client_get_etype, &cdata);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("get_data_proc returned %d (%s)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan enctype = *((krb5_enctype *)cdata->data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*get_data_proc)(context, rock,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5plugin_preauth_client_free_etype, &cdata);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pa_pkinit_parse_rep(context, plgctx, reqctx, request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan in_padata, enctype, as_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encoded_previous_request);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_client_process: returning %d (%s)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_client_tryagain(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *plugin_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *request_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_get_init_creds_opt *gic_opt,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan preauth_get_client_data_proc get_data_proc,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _krb5_preauth_client_rock *rock,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_kdc_req *request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *encoded_request_body,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *encoded_previous_request,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data *in_padata,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error *err_reply,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_prompter_fct prompter,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *prompter_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan preauth_get_as_key_proc gak_fct,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *gak_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *salt,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *s2kparams,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_keyblock *as_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_pa_data ***out_padata)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_context plgctx = (pkinit_context)plugin_context;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_context reqctx = (pkinit_req_context)request_context;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_typed_data **typed_data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data scratch;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_external_principal_identifier **krb5_trusted_certifiers = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_algorithm_identifier **algId = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int do_again = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_client_tryagain %p %p %p %p\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan context, plgctx, reqctx, request);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->pa_type != in_padata->pa_type)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)err_reply->e_data.data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan err_reply->e_data.length, "/tmp/client_edata");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_decode_krb5_typed_data(&err_reply->e_data, &typed_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("decode_krb5_typed_data failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(typed_data[0]->data, typed_data[0]->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/client_typed_data");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan OCTETDATA_TO_KRB5DATA(typed_data[0], &scratch);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(typed_data[0]->type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case TD_TRUSTED_CERTIFIERS:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case TD_INVALID_CERTIFICATES:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_decode_krb5_td_trusted_certifiers(&scratch,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &krb5_trusted_certifiers);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to decode sequence of trusted certifiers\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_process_td_trusted_certifiers(context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->cryptoctx, reqctx->cryptoctx, reqctx->idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_trusted_certifiers, typed_data[0]->type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan do_again = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case TD_DH_PARAMETERS:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_decode_krb5_td_dh_parameters(&scratch, &algId);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to decode td_dh_parameters\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_process_td_dh_params(context, plgctx->cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx, reqctx->idctx, algId,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &reqctx->opts->dh_size);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan do_again = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (do_again) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pa_pkinit_gen_req(context, plgctx, reqctx, request, in_padata,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan out_padata, prompter, prompter_data, gic_opt);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_trusted_certifiers != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_external_principal_identifier(&krb5_trusted_certifiers);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (typed_data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_typed_data(&typed_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_algorithm_identifiers(&algId);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_client_tryagain: returning %d (%s)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_client_get_flags(krb5_context kcontext, krb5_preauthtype patype)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return PA_REAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_preauthtype supported_client_pa_types[] = {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan KRB5_PADATA_PK_AS_REP,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan KRB5_PADATA_PK_AS_REQ,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan KRB5_PADATA_PK_AS_REP_OLD,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan KRB5_PADATA_PK_AS_REQ_OLD,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanvoid
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_client_req_init(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *plugin_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void **request_context)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_req_context *reqctx = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_context *plgctx = (struct _pkinit_context *)plugin_context;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *request_context = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx = (struct _pkinit_req_context *) malloc(sizeof(*reqctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memset(reqctx, 0, sizeof(*reqctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->magic = PKINIT_REQ_CTX_MAGIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->cryptoctx = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->idctx = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->idopts = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_req_opts(&reqctx->opts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->require_eku = plgctx->opts->require_eku;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->accept_secondary_eku = plgctx->opts->accept_secondary_eku;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->dh_or_rsa = plgctx->opts->dh_or_rsa;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->allow_upn = plgctx->opts->allow_upn;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->opts->require_crl_checking = plgctx->opts->require_crl_checking;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_req_crypto(&reqctx->cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_identity_crypto(&reqctx->idctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_dup_identity_opts(plgctx->idopts, &reqctx->idopts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *request_context = (void *) reqctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning reqctx at %p\n", __FUNCTION__, reqctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->idctx != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_identity_crypto(reqctx->idctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->cryptoctx != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_req_crypto(reqctx->cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->opts != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_req_opts(reqctx->opts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->idopts != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_identity_opts(reqctx->idopts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(reqctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanvoid
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_client_req_fini(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *plugin_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *request_context)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_req_context *reqctx =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (struct _pkinit_req_context *)request_context;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: received reqctx at %p\n", __FUNCTION__, reqctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->magic != PKINIT_REQ_CTX_MAGIC) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Bad magic value (%x) in req ctx\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, reqctx->magic);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->opts != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_req_opts(reqctx->opts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->cryptoctx != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_req_crypto(reqctx->cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->idctx != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_identity_crypto(reqctx->idctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->idopts != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_identity_opts(reqctx->idopts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(reqctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_client_profile(krb5_context context, pkinit_context plgctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* This should clean up anything allocated in pkinit_init_client_profile */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_client_profile(krb5_context context, pkinit_context plgctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_client_plugin_init(krb5_context context, void **blob)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_context *ctx = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx = (struct _pkinit_context *)calloc(1, sizeof(*ctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memset(ctx, 0, sizeof(*ctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->magic = PKINIT_CTX_MAGIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->opts = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->cryptoctx = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->idopts = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_accessor_init();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_plg_opts(&ctx->opts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_plg_crypto(&ctx->cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_identity_opts(&ctx->idopts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_client_profile(context, ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *blob = ctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning plgctx at %p\n", __FUNCTION__, ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanerrout:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_client_plugin_fini(context, ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_client_plugin_fini(krb5_context context, void *blob)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_context *ctx = (struct _pkinit_context *)blob;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx == NULL || ctx->magic != PKINIT_CTX_MAGIC) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pkinit_lib_fini: got bad plgctx (%p)!\n", ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: got plgctx at %p\n", __FUNCTION__, ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_client_profile(context, ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_identity_opts(ctx->idopts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_plg_crypto(ctx->cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_plg_opts(ctx->opts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanadd_string_to_array(krb5_context context, char ***array, const char *addition)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char **out = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (*array == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan out = malloc(2 * sizeof(char *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (out == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan out[1] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan out[0] = strdup(addition);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (out[0] == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(out);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char **a = *array;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; a[i] != NULL; i++);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan out = malloc( (i + 2) * sizeof(char *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (out == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; a[i] != NULL; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan out[i] = a[i];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan out[i++] = strdup(addition);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (out == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(out);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan out[i] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(*array);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *array = out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanhandle_gic_opt(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_context *plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const char *attr,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const char *value)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (strcmp(attr, "X509_user_identity") == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx->idopts->identity != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, KRB5_PREAUTH_FAILED,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "X509_user_identity can not be given twice\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->idopts->identity = strdup(value);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx->idopts->identity == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, ENOMEM,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "Could not duplicate X509_user_identity value\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (strcmp(attr, "X509_anchors") == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = add_string_to_array(context, &plgctx->idopts->anchors, value);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (strcmp(attr, "flag_RSA_PROTOCOL") == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (strcmp(value, "yes") == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Setting flag to use RSA_PROTOCOL\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->opts->dh_or_rsa = RSA_PROTOCOL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash } else if (strcmp(attr, "PIN") == 0) {
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash /* Solaris Kerberos: handle our PIN attr */
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash plgctx->idopts->PIN = strdup(value);
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash if (plgctx->idopts->PIN == NULL)
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_client_gic_opt(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *plugin_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_get_init_creds_opt *gic_opt,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const char *attr,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const char *value)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_context *plgctx = (struct _pkinit_context *)plugin_context;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("(pkinit) received '%s' = '%s'\n", attr, value);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = handle_gic_opt(context, plgctx, attr, value);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstruct krb5plugin_preauth_client_ftable_v1 preauthentication_client_1 = {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "pkinit", /* name */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan supported_client_pa_types, /* pa_type_list */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL, /* enctype_list */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_client_plugin_init, /* (*init) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_client_plugin_fini, /* (*fini) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_client_get_flags, /* (*flags) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_client_req_init, /* (*client_req_init) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_client_req_fini, /* (*client_req_fini) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_client_process, /* (*process) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_client_tryagain, /* (*tryagain) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_client_gic_opt /* (*gic_opt) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan};