pkinit_crypto_openssl.c revision 31a2903539e29171f5c5da80e5c9616c70108116
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * COPYRIGHT (C) 2006,2007
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * ALL RIGHTS RESERVED
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Permission is granted to use, copy, create derivative works
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * and redistribute this software and such derivative works
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * for any purpose, so long as the name of The University of
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Michigan is not used in any advertising or publicity
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * pertaining to the use of distribution of this software
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * without specific, written prior authorization. If the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * above copyright notice or any other identification of the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * University of Michigan is included in any copy of any
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * portion of this software, then the disclaimer below must
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * also be included.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * SUCH DAMAGES.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <errno.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <string.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <stdio.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <stdlib.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <dlfcn.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <unistd.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <dirent.h>
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include <libintl.h>
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan#include "k5-int.h"
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Q: What is this SILLYDECRYPT stuff about?
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * A: When using the ActivCard Linux pkcs11 library (v2.0.1),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * the decrypt function fails. By inserting an extra
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * function call, which serves nothing but to change the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * stack, we were able to work around the issue. If the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * ActivCard library is fixed in the future, this
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * definition and related code can be removed.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#define SILLYDECRYPT
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include "pkinit_crypto_openssl.h"
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Solaris Kerberos:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Changed to a switch statement so gettext() can be used
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * for internationization.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Use defined constants rather than raw numbers for error codes.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic char *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkcs11_error_table(short code) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch (code) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_OK:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("ok"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_CANCEL:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("cancel"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_HOST_MEMORY:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("host memory"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_SLOT_ID_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("slot id invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_GENERAL_ERROR:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("general error"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_FUNCTION_FAILED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("function failed"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_ARGUMENTS_BAD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("arguments bad"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_NO_EVENT:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("no event"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_NEED_TO_CREATE_THREADS:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("need to create threads"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_CANT_LOCK:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("cant lock"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_ATTRIBUTE_READ_ONLY:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("attribute read only"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_ATTRIBUTE_SENSITIVE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("attribute sensitive"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_ATTRIBUTE_TYPE_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("attribute type invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_ATTRIBUTE_VALUE_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("attribute value invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_DATA_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("data invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_DATA_LEN_RANGE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("data len range"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_DEVICE_ERROR:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("device error"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_DEVICE_MEMORY:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("device memory"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_DEVICE_REMOVED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("device removed"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_ENCRYPTED_DATA_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("encrypted data invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_ENCRYPTED_DATA_LEN_RANGE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("encrypted data len range"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_FUNCTION_CANCELED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("function canceled"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_FUNCTION_NOT_PARALLEL:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("function not parallel"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_FUNCTION_NOT_SUPPORTED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("function not supported"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_KEY_HANDLE_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("key handle invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_KEY_SIZE_RANGE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("key size range"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_KEY_TYPE_INCONSISTENT:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("key type inconsistent"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_KEY_NOT_NEEDED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("key not needed"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_KEY_CHANGED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("key changed"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_KEY_NEEDED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("key needed"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_KEY_INDIGESTIBLE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("key indigestible"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_KEY_FUNCTION_NOT_PERMITTED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("key function not permitted"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_KEY_NOT_WRAPPABLE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("key not wrappable"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_KEY_UNEXTRACTABLE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("key unextractable"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_MECHANISM_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("mechanism invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_MECHANISM_PARAM_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("mechanism param invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_OBJECT_HANDLE_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("object handle invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_OPERATION_ACTIVE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("operation active"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_OPERATION_NOT_INITIALIZED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("operation not initialized"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_PIN_INCORRECT:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("pin incorrect"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_PIN_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("pin invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_PIN_LEN_RANGE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("pin len range"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_PIN_EXPIRED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("pin expired"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_PIN_LOCKED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("pin locked"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_SESSION_CLOSED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("session closed"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_SESSION_COUNT:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("session count"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_SESSION_HANDLE_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("session handle invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("session parallel not supported"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_SESSION_READ_ONLY:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("session read only"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_SESSION_EXISTS:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("session exists"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_SESSION_READ_ONLY_EXISTS:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("session read only exists"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_SESSION_READ_WRITE_SO_EXISTS:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("session read write so exists"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_SIGNATURE_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("signature invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_SIGNATURE_LEN_RANGE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("signature len range"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_TEMPLATE_INCOMPLETE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("template incomplete"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_TEMPLATE_INCONSISTENT:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("template inconsistent"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_TOKEN_NOT_PRESENT:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("token not present"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_TOKEN_NOT_RECOGNIZED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("token not recognized"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_TOKEN_WRITE_PROTECTED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("token write protected"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_UNWRAPPING_KEY_HANDLE_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("unwrapping key handle invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_UNWRAPPING_KEY_SIZE_RANGE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("unwrapping key size range"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("unwrapping key type inconsistent"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_USER_ALREADY_LOGGED_IN:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("user already logged in"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_USER_NOT_LOGGED_IN:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("user not logged in"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_USER_PIN_NOT_INITIALIZED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("user pin not initialized"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_USER_TYPE_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("user type invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("user another already logged in"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_USER_TOO_MANY_TYPES:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("user too many types"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_WRAPPED_KEY_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("wrapped key invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_WRAPPED_KEY_LEN_RANGE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("wrapped key len range"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_WRAPPING_KEY_HANDLE_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("wrapping key handle invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_WRAPPING_KEY_SIZE_RANGE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("wrapping key size range"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_WRAPPING_KEY_TYPE_INCONSISTENT:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("wrapping key type inconsistent"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_RANDOM_SEED_NOT_SUPPORTED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("random seed not supported"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_RANDOM_NO_RNG:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("random no rng"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_DOMAIN_PARAMS_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("domain params invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_BUFFER_TOO_SMALL:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("buffer too small"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_SAVED_STATE_INVALID:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("saved state invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_INFORMATION_SENSITIVE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("information sensitive"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_STATE_UNSAVEABLE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("state unsaveable"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_CRYPTOKI_NOT_INITIALIZED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("cryptoki not initialized"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_CRYPTOKI_ALREADY_INITIALIZED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("cryptoki already initialized"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_MUTEX_BAD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("mutex bad"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_MUTEX_NOT_LOCKED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("mutex not locked"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CKR_FUNCTION_REJECTED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("function rejected"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("unknown error"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* DH parameters */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanunsigned char pkinit_1024_dhprime[128] = {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanunsigned char pkinit_2048_dhprime[2048/8] = {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanunsigned char pkinit_4096_dhprime[4096/8] = {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan/* Solaris Kerberos */
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalanstatic k5_mutex_t oids_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int pkinit_oids_refs = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context ctx = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* initialize openssl routines */
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan /* Solaris Kerberos */
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan retval = openssl_init();
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan if (retval != 0)
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx = (pkinit_plg_crypto_context)malloc(sizeof(*ctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memset(ctx, 0, sizeof(*ctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: initializing openssl crypto context at %p\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_pkinit_oids(ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_dh_params(ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *cryptoctx = ctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanout:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval && ctx != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_plg_crypto(ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanvoid
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_plg_crypto(pkinit_plg_crypto_context cryptoctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: freeing context at %p\n", __FUNCTION__, cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cryptoctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_pkinit_oids(cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_dh_params(cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_identity_crypto(pkinit_identity_crypto_context *idctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context ctx = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx = (pkinit_identity_crypto_context)malloc(sizeof(*ctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memset(ctx, 0, sizeof(*ctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_certs(ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_init_pkcs11(ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning ctx at %p\n", __FUNCTION__, ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *idctx = ctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanout:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_identity_crypto(ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanvoid
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_identity_crypto(pkinit_identity_crypto_context idctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: freeing ctx at %p\n", __FUNCTION__, idctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_certs(idctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_pkcs11(idctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(idctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_req_crypto(pkinit_req_crypto_context *cryptoctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context ctx = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cryptoctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx = (pkinit_req_crypto_context)malloc(sizeof(*ctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memset(ctx, 0, sizeof(*ctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->dh = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->received_cert = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *cryptoctx = ctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning ctx at %p\n", __FUNCTION__, ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanvoid
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_req_crypto(pkinit_req_crypto_context req_cryptoctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (req_cryptoctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: freeing ctx at %p\n", __FUNCTION__, req_cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (req_cryptoctx->dh != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_free(req_cryptoctx->dh);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (req_cryptoctx->received_cert != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_free(req_cryptoctx->received_cert);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(req_cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_pkinit_oids(pkinit_plg_crypto_context ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int nid = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * If OpenSSL already knows about the OID, use the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * existing definition. Otherwise, create an OID object.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan #define CREATE_OBJ_IF_NEEDED(oid, vn, sn, ln) \
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nid = OBJ_txt2nid(oid); \
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (nid == NID_undef) { \
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nid = OBJ_create(oid, sn, ln); \
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (nid == NID_undef) { \
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Error creating oid object for '%s'\n", oid); \
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out; \
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } \
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } \
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->vn = OBJ_nid2obj(nid);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan /* Solaris Kerberos */
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan retval = k5_mutex_lock(&oids_mutex);
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan if (retval != 0)
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan goto out;
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.2", id_pkinit_san,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "id-pkinit-san", "KRB5PrincipalName");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.1", id_pkinit_authData,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "id-pkinit-authdata", "PKINIT signedAuthPack");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.2", id_pkinit_DHKeyData,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "id-pkinit-DHKeyData", "PKINIT dhSignedData");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.3", id_pkinit_rkeyData,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "id-pkinit-rkeyData", "PKINIT encKeyPack");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.4", id_pkinit_KPClientAuth,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "id-pkinit-KPClientAuth", "PKINIT Client EKU");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.5", id_pkinit_KPKdc,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "id-pkinit-KPKdc", "KDC EKU");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#if 0
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.2.840.113549.1.7.1", id_pkinit_authData9,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "id-pkcs7-data", "PKCS7 data");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* See note in pkinit_pkcs7type2oid() */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->id_pkinit_authData9 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.2", id_ms_kp_sc_logon,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "id-ms-kp-sc-logon EKU", "Microsoft SmartCard Login EKU");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.3", id_ms_san_upn,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "id-ms-san-upn", "Microsoft Universal Principal Name");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.5.5.7.3.1", id_kp_serverAuth,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "id-kp-serverAuth EKU", "Server Authentication EKU");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Success */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_oids_refs++;
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan /* Solaris Kerberos */
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan k5_mutex_unlock(&oids_mutex);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanout:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanget_cert(char *filename, X509 **retcert)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *cert = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO *tmp = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int code;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (filename == NULL || retcert == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *retcert = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tmp = BIO_new(BIO_s_file());
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (tmp == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = BIO_read_filename(tmp, filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (code == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = errno;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cert = (X509 *) PEM_read_bio_X509(tmp, NULL, NULL, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cert == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EIO;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to read certificate from %s\n", filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *retcert = cert;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (tmp != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_free(tmp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanget_key(char *filename, EVP_PKEY **retkey)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_PKEY *pkey = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO *tmp = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int code;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (filename == NULL || retkey == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tmp = BIO_new(BIO_s_file());
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (tmp == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = BIO_read_filename(tmp, filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (code == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = errno;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkey = (EVP_PKEY *) PEM_read_bio_PrivateKey(tmp, NULL, NULL, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkey == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EIO;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to read private key from %s\n", filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *retkey = pkey;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (tmp != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_free(tmp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Only call OBJ_cleanup once! */
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan /* Solaris Kerberos: locking */
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan k5_mutex_lock(&oids_mutex);
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan if (--pkinit_oids_refs == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan OBJ_cleanup();
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan k5_mutex_unlock(&oids_mutex);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_dh_params(pkinit_plg_crypto_context plgctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->dh_1024 = DH_new();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx->dh_1024 == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->dh_1024->p = BN_bin2bn(pkinit_1024_dhprime,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sizeof(pkinit_1024_dhprime), NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((plgctx->dh_1024->g = BN_new()) == NULL ||
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (plgctx->dh_1024->q = BN_new()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_set_word(plgctx->dh_1024->g, DH_GENERATOR_2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_rshift1(plgctx->dh_1024->q, plgctx->dh_1024->p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->dh_2048 = DH_new();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx->dh_2048 == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->dh_2048->p = BN_bin2bn(pkinit_2048_dhprime,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sizeof(pkinit_2048_dhprime), NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((plgctx->dh_2048->g = BN_new()) == NULL ||
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (plgctx->dh_2048->q = BN_new()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_set_word(plgctx->dh_2048->g, DH_GENERATOR_2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_rshift1(plgctx->dh_2048->q, plgctx->dh_2048->p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->dh_4096 = DH_new();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx->dh_4096 == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->dh_4096->p = BN_bin2bn(pkinit_4096_dhprime,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sizeof(pkinit_4096_dhprime), NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((plgctx->dh_4096->g = BN_new()) == NULL ||
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (plgctx->dh_4096->q = BN_new()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_set_word(plgctx->dh_4096->g, DH_GENERATOR_2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_rshift1(plgctx->dh_4096->q, plgctx->dh_4096->p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_fini_dh_params(plgctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_dh_params(pkinit_plg_crypto_context plgctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx->dh_1024 != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_free(plgctx->dh_1024);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx->dh_2048 != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_free(plgctx->dh_2048);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plgctx->dh_4096 != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_free(plgctx->dh_4096);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->dh_1024 = plgctx->dh_2048 = plgctx->dh_4096 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_certs(pkinit_identity_crypto_context ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < MAX_CREDS_ALLOWED; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->creds[i] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->my_certs = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->cert_index = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->my_key = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->trustedCAs = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->intermediateCAs = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->revoked = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_certs(pkinit_identity_crypto_context ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx->my_certs != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_pop_free(ctx->my_certs, X509_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx->my_key != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_PKEY_free(ctx->my_key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx->trustedCAs != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_pop_free(ctx->trustedCAs, X509_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx->intermediateCAs != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_pop_free(ctx->intermediateCAs, X509_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx->revoked != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_CRL_pop_free(ctx->revoked, X509_CRL_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_pkcs11(pkinit_identity_crypto_context ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->p11_module_name = strdup(PKCS11_MODNAME);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx->p11_module_name == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->p11_module = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->slotid = PK_NOSLOT;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->token_label = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->cert_label = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->session = CK_INVALID_HANDLE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->p11 = NULL;
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash ctx->p11flags = 0; /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->pkcs11_method = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_pkcs11(pkinit_identity_crypto_context ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx->p11 != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx->session) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->p11->C_CloseSession(ctx->session);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->session = CK_INVALID_HANDLE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Solaris Kerberos:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Only call C_Finalize if the process was not already using pkcs11.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx->finalize_pkcs11 == TRUE)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->p11->C_Finalize(NULL_PTR);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->p11 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx->p11_module != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_C_UnloadModule(ctx->p11_module);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->p11_module = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx->p11_module_name != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(ctx->p11_module_name);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx->token_label != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(ctx->token_label);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx->cert_id != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(ctx->cert_id);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx->cert_label != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(ctx->cert_label);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_identity_set_prompter(pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_prompter_fct prompter,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *prompter_data)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->prompter = prompter;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->prompter_data = prompter_data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancms_signeddata_create(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int cms_msg_type,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int include_certchain,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **signed_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *signed_data_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KRB_ERR_GENERIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7 *p7 = NULL, *inner_p7 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_SIGNED *p7s = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_SIGNER_INFO *p7si = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_TYPE *pkinit_data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(X509) * cert_stack = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OCTET_STRING *digest_attr = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_MD_CTX ctx, ctx2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const EVP_MD *md_tmp = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *digestInfo_buf = NULL, *abuf = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int md_len, md_len2, alen, digestInfo_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(X509_ATTRIBUTE) * sk;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *sig = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int sig_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_ALGOR *alg = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OCTET_STRING *digest = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int alg_len = 0, digest_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *y = NULL, *alg_buf = NULL, *digest_buf = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *cert = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OBJECT *oid = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (signed_data == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (signed_data_len == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* start creating PKCS7 data */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p7 = PKCS7_new()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7->type = OBJ_nid2obj(NID_pkcs7_signed);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p7s = PKCS7_SIGNED_new()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7->d.sign = p7s;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!ASN1_INTEGER_set(p7s->version, 3))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create a cert chain that has at least the signer's certificate */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((cert_stack = sk_X509_new_null()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!include_certchain) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("only including signer's certificate\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_push(cert_stack, X509_dup(cert));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create a cert chain */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE *certstore = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_CTX certctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(X509) *certstack = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char buf[DN_BUF_LEN];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i = 0, size = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((certstore = X509_STORE_new()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("building certificate chain\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_set_verify_cb_func(certstore, openssl_callback);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_CTX_init(&certctx, certstore, cert,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->intermediateCAs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_CTX_trusted_stack(&certctx, id_cryptoctx->trustedCAs);
7801e5e8b5bc4af34929c54a02cfb78398da08ddMark Phalan /* Solaris Kerberos */
7801e5e8b5bc4af34929c54a02cfb78398da08ddMark Phalan if (X509_verify_cert(&certctx) <= 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to create a certificate chain: %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_verify_cert_error_string(X509_STORE_CTX_get_error(&certctx)));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!sk_X509_num(id_cryptoctx->trustedCAs))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("No trusted CAs found. Check your X509_anchors\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan certstack = X509_STORE_CTX_get1_chain(&certctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size = sk_X509_num(certstack);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("size of certificate chain = %d\n", size);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for(i = 0; i < size - 1; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *x = sk_X509_value(certstack, i);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("cert #%d: %s\n", i, buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_push(cert_stack, X509_dup(x));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_CTX_cleanup(&certctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_free(certstore);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_pop_free(certstack, X509_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7s->cert = cert_stack;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* fill-in PKCS7_SIGNER_INFO */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p7si = PKCS7_SIGNER_INFO_new()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!ASN1_INTEGER_set(p7si->version, 1))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!X509_NAME_set(&p7si->issuer_and_serial->issuer,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_get_issuer_name(cert)))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* because ASN1_INTEGER_set is used to set a 'long' we will do
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * things the ugly way. */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!(p7si->issuer_and_serial->serial =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* will not fill-out EVP_PKEY because it's on the smartcard */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Set digest algs */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha1);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (p7si->digest_alg->parameter != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_TYPE_free(p7si->digest_alg->parameter);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p7si->digest_alg->parameter = ASN1_TYPE_new()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7si->digest_alg->parameter->type = V_ASN1_NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Set sig algs */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (p7si->digest_enc_alg->parameter != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_TYPE_free(p7si->digest_enc_alg->parameter);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha1WithRSAEncryption);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new()))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7si->digest_enc_alg->parameter->type = V_ASN1_NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* pick the correct oid for the eContentInfo */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan oid = pkinit_pkcs7type2oid(plg_cryptoctx, cms_msg_type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (oid == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cms_msg_type == CMS_SIGN_DRAFT9) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* don't include signed attributes for pa-type 15 request */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan abuf = data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan alen = data_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* add signed attributes */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* compute sha1 digest over the EncapsulatedContentInfo */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_MD_CTX_init(&ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_DigestUpdate(&ctx, data, data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan md_tmp = EVP_MD_CTX_md(&ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_DigestFinal_ex(&ctx, md_data, &md_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create a message digest attr */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan digest_attr = ASN1_OCTET_STRING_new();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan V_ASN1_OCTET_STRING, (char *) digest_attr);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create a content-type attr */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan V_ASN1_OBJECT, oid);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create the signature over signed attributes. get DER encoded value */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* This is the place where smartcard signature needs to be calculated */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk = p7si->auth_attr;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (abuf == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Some tokens can only do RSAEncryption without sha1 hash */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * function and the hash value into an ASN.1 value of type DigestInfo
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * DigestInfo::=SEQUENCE {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * digestAlgorithm AlgorithmIdentifier,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * digest OCTET STRING }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->pkcs11_method == 1 &&
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->mech == CKM_RSA_PKCS) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("mech = CKM_RSA_PKCS\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_MD_CTX_init(&ctx2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* if this is not draft9 request, include digest signed attribute */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cms_msg_type != CMS_SIGN_DRAFT9)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_DigestInit_ex(&ctx2, md_tmp, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_DigestInit_ex(&ctx2, EVP_sha1(), NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_DigestUpdate(&ctx2, abuf, alen);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_DigestFinal_ex(&ctx2, md_data2, &md_len2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan alg = X509_ALGOR_new();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (alg == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan alg->algorithm = OBJ_nid2obj(NID_sha1);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan alg->parameter = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan alg_len = i2d_X509_ALGOR(alg, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan alg_buf = (unsigned char *)malloc(alg_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (alg_buf == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan digest = ASN1_OCTET_STRING_new();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (digest == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OCTET_STRING_set(digest, md_data2, (int)md_len2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan digest_len = i2d_ASN1_OCTET_STRING(digest, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan digest_buf = (unsigned char *)malloc(digest_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (digest_buf == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan digestInfo_len = ASN1_object_size(1, (int)(alg_len + digest_len),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan y = digestInfo_buf = (unsigned char *)malloc(digestInfo_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (digestInfo_buf == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&y, 1, (int)(alg_len + digest_len), V_ASN1_SEQUENCE,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan V_ASN1_UNIVERSAL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_X509_ALGOR(alg, &y);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_ASN1_OCTET_STRING(digest, &y);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_SIG
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("signing buffer\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer(digestInfo_buf, digestInfo_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(digestInfo_buf, digestInfo_len, "/tmp/pkcs7_tosign");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_sign_data(context, id_cryptoctx, digestInfo_buf,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan digestInfo_len, &sig, &sig_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("mech = %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->pkcs11_method == 1 ? "CKM_SHA1_RSA_PKCS" : "FS");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_sign_data(context, id_cryptoctx, abuf, alen,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &sig, &sig_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_SIG
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer(sig, sig_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cms_msg_type != CMS_SIGN_DRAFT9)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(abuf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Add signature */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!ASN1_STRING_set(p7si->enc_digest, (unsigned char *) sig,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int)sig_len)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned long err = ERR_peek_error();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "%s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ERR_error_string(err, NULL));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to add a signed digest attribute\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* adder signer_info to pkcs7 signed */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!PKCS7_add_signer(p7, p7si))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* start on adding data to the pkcs7 signed */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((inner_p7 = PKCS7_new()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((pkinit_data = ASN1_TYPE_new()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_data->type = V_ASN1_OCTET_STRING;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((pkinit_data->value.octet_string = ASN1_OCTET_STRING_new()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!ASN1_OCTET_STRING_set(pkinit_data->value.octet_string, data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int)data_len)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned long err = ERR_peek_error();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "%s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ERR_error_string(err, NULL));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to add pkcs7 data\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!PKCS7_set0_type_other(inner_p7, OBJ_obj2nid(oid), pkinit_data))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (p7s->contents != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_free(p7s->contents);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7s->contents = inner_p7;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *signed_data_len = i2d_PKCS7(p7, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!(*signed_data_len)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned long err = ERR_peek_error();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "%s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ERR_error_string(err, NULL));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to der encode pkcs7\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p = *signed_data =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned char *) malloc((size_t)*signed_data_len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* DER encode PKCS7 data */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = i2d_PKCS7(p7, &p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned long err = ERR_peek_error();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "%s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ERR_error_string(err, NULL));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to der encode pkcs7\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cms_msg_type == CMS_SIGN_CLIENT) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(*signed_data, *signed_data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/client_pkcs7_signeddata");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cms_msg_type == CMS_SIGN_SERVER) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(*signed_data, *signed_data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/kdc_pkcs7_signeddata");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(*signed_data, *signed_data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/draft9_pkcs7_signeddata");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup2:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cms_msg_type != CMS_SIGN_DRAFT9)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_MD_CTX_cleanup(&ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->pkcs11_method == 1 &&
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->mech == CKM_RSA_PKCS) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_MD_CTX_cleanup(&ctx2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (digest_buf != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(digest_buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (digestInfo_buf != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(digestInfo_buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (alg_buf != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(alg_buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (digest != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OCTET_STRING_free(digest);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (alg != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_ALGOR_free(alg);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (p7 != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_free(p7);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (sig != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(sig);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancms_signeddata_verify(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int cms_msg_type,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int require_crl_checking,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *signed_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int signed_data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **authz_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *authz_data_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7 *p7 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO *out = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int flags = PKCS7_NOVERIFY, i = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int vflags = 0, size = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const unsigned char *p = signed_data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_SIGNER_INFO *si = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *x = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE *store = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_CTX cert_ctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(X509) *intermediateCAs = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(X509_CRL) *revoked = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(X509) *verified_chain = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OBJECT *oid = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_external_principal_identifier **krb5_verified_chain = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *authz = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char buf[DN_BUF_LEN];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(signed_data, signed_data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/client_received_pkcs7_signeddata");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Do this early enough to create the shadow OID for pkcs7-data if needed */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan oid = pkinit_pkcs7type2oid(plgctx, cms_msg_type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (oid == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* decode received PKCS7 message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p7 = d2i_PKCS7(NULL, &p, (int)signed_data_len)) == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned long err = ERR_peek_error();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "%s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ERR_error_string(err, NULL));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed to decode message: %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, ERR_error_string(err, NULL));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* verify that the received message is PKCS7 SignedData message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (OBJ_obj2nid(p7->type) != NID_pkcs7_signed) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Expected id-signedData PKCS7 msg (received type = %d)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan OBJ_obj2nid(p7->type));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "wrong oid\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* setup to verify X509 certificate used to sign PKCS7 message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!(store = X509_STORE_new()))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* check if we are inforcing CRL checking */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan vflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (require_crl_checking)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_set_verify_cb_func(store, openssl_callback);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_set_verify_cb_func(store, openssl_callback_ignore_crls);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_set_flags(store, vflags);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* get the signer's information from the PKCS7 message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((si_sk = PKCS7_get_signer_info(p7)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((si = sk_PKCS7_SIGNER_INFO_value(si_sk, 0)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((x = PKCS7_cert_from_signer_info(p7, si)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create available CRL information (get local CRLs and include CRLs
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * received in the PKCS7 message
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idctx->revoked == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan revoked = p7->d.sign->crl;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else if (p7->d.sign->crl == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan revoked = idctx->revoked;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size = sk_X509_CRL_num(idctx->revoked);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan revoked = sk_X509_CRL_new_null();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < size; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_CRL_push(revoked, sk_X509_CRL_value(idctx->revoked, i));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size = sk_X509_num(p7->d.sign->crl);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < size; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_CRL_push(revoked, sk_X509_CRL_value(p7->d.sign->crl, i));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create available intermediate CAs chains (get local intermediateCAs and
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * include the CA chain received in the PKCS7 message
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idctx->intermediateCAs == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan intermediateCAs = p7->d.sign->cert;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else if (p7->d.sign->cert == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan intermediateCAs = idctx->intermediateCAs;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size = sk_X509_num(idctx->intermediateCAs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan intermediateCAs = sk_X509_new_null();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < size; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_push(intermediateCAs,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_value(idctx->intermediateCAs, i));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size = sk_X509_num(p7->d.sign->cert);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < size; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_push(intermediateCAs, sk_X509_value(p7->d.sign->cert, i));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* initialize x509 context with the received certificate and
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * trusted and intermediate CA chains and CRLs
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!X509_STORE_CTX_init(&cert_ctx, store, x, intermediateCAs))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_CTX_set0_crls(&cert_ctx, revoked);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* add trusted CAs certificates for cert verification */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idctx->trustedCAs != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_CTX_trusted_stack(&cert_ctx, idctx->trustedCAs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("unable to find any trusted CAs\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_CERTCHAIN
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (intermediateCAs != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size = sk_X509_num(intermediateCAs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("untrusted cert chain of size %d\n", size);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < size; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_value(intermediateCAs, i)), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("cert #%d: %s\n", i, buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idctx->trustedCAs != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size = sk_X509_num(idctx->trustedCAs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("trusted cert chain of size %d\n", size);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < size; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_value(idctx->trustedCAs, i)), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("cert #%d: %s\n", i, buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (revoked != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size = sk_X509_CRL_num(revoked);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("CRL chain of size %d\n", size);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < size; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_CRL *crl = sk_X509_CRL_value(revoked, i);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_CRL_get_issuer(crl), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("crls by CA #%d: %s\n", i , buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i = X509_verify_cert(&cert_ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (i <= 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int j = X509_STORE_CTX_get_error(&cert_ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->received_cert = X509_dup(cert_ctx.current_cert);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(j) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case X509_V_ERR_CERT_REVOKED:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_REVOKED_CERTIFICATE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case X509_V_ERR_UNABLE_TO_GET_CRL:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_REVOCATION_STATUS_UNKNOWN;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_INVALID_CERTIFICATE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->received_cert), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("problem with cert DN = %s (error=%d) %s\n", buf, j,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_verify_cert_error_string(j));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "%s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_verify_cert_error_string(j));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_CERTCHAIN
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size = sk_X509_num(p7->d.sign->cert);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("received cert chain of size %d\n", size);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (j = 0; j < size; j++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *tmp_cert = sk_X509_value(p7->d.sign->cert, j);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(tmp_cert), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("cert #%d: %s\n", j, buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* retrieve verified certificate chain */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan verified_chain = X509_STORE_CTX_get1_chain(&cert_ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_CTX_cleanup(&cert_ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (i <= 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan out = BIO_new(BIO_s_mem());
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cms_msg_type == CMS_SIGN_DRAFT9)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan flags |= PKCS7_NOATTR;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (PKCS7_verify(p7, NULL, store, NULL, out, flags)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int valid_oid = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!OBJ_cmp(p7->d.sign->contents->type, oid))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan valid_oid = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else if (cms_msg_type == CMS_SIGN_DRAFT9) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Various implementations of the pa-type 15 request use
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * different OIDS. We check that the returned object
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * has any of the acceptable OIDs
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OBJECT *client_oid = NULL, *server_oid = NULL, *rsa_oid = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan client_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_CLIENT);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan server_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_SERVER);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rsa_oid = pkinit_pkcs7type2oid(plgctx, CMS_ENVEL_SERVER);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!OBJ_cmp(p7->d.sign->contents->type, client_oid) ||
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan !OBJ_cmp(p7->d.sign->contents->type, server_oid) ||
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan !OBJ_cmp(p7->d.sign->contents->type, rsa_oid))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan valid_oid = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (valid_oid)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("PKCS7 Verification successful\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("wrong oid in eContentType\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer(p7->d.sign->contents->type->data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned int)p7->d.sign->contents->type->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "wrong oid\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned long err = ERR_peek_error();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(ERR_GET_REASON(err)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case PKCS7_R_DIGEST_FAILURE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case PKCS7_R_SIGNATURE_FAILURE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_INVALID_SIG;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("PKCS7 Verification failure\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "%s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ERR_error_string(err, NULL));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* transfer the data from PKCS7 message into return buffer */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (size = 0;;) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*data = realloc(*data, size + 1024 * 10)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i = BIO_read(out, &((*data)[size]), 1024 * 10);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (i <= 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size += i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *data_len = size;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->received_cert = X509_dup(x);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* generate authorization data */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (authz_data == NULL || authz_data_len == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *authz_data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = create_identifiers_from_stack(verified_chain,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &krb5_verified_chain);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("create_identifiers_from_stack failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_td_trusted_certifiers((const krb5_external_principal_identifier **)krb5_verified_chain, &authz);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("encode_krb5_td_trusted_certifiers failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)authz->data, authz->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/kdc_ad_initial_verified_cas");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *authz_data = (unsigned char *)malloc(authz->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (*authz_data == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(*authz_data, authz->data, authz->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *authz_data_len = authz->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan out:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (out != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_free(out);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (store != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_free(store);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (p7 != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idctx->intermediateCAs != NULL && p7->d.sign->cert)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_free(intermediateCAs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idctx->revoked != NULL && p7->d.sign->crl)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_CRL_free(revoked);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_free(p7);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (verified_chain != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_pop_free(verified_chain, X509_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_verified_chain != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_external_principal_identifier(&krb5_verified_chain);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (authz != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_data(context, authz);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancms_envelopeddata_create(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_preauthtype pa_type,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int include_certchain,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *key_pack,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int key_pack_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **out,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *out_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KRB_ERR_GENERIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7 *p7 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO *in = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL, *signed_data = NULL, *enc_data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int signed_data_len = 0, enc_data_len = 0, flags = PKCS7_BINARY;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(X509) *encerts = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const EVP_CIPHER *cipher = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int cms_msg_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create the PKCS7 SignedData portion of the PKCS7 EnvelopedData */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch ((int)pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cms_msg_type = CMS_SIGN_DRAFT9;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cms_msg_type = CMS_ENVEL_SERVER;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = cms_signeddata_create(context, plgctx, reqctx, idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cms_msg_type, include_certchain, key_pack, key_pack_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &signed_data, (unsigned int *)&signed_data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to create pkcs7 signed data\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* check we have client's certificate */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->received_cert == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encerts = sk_X509_new_null();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_push(encerts, reqctx->received_cert);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cipher = EVP_des_ede3_cbc();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan in = BIO_new(BIO_s_mem());
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch (pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan prepare_enc_data(signed_data, signed_data_len, &enc_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &enc_data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = BIO_write(in, enc_data, enc_data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval != enc_data_len) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("BIO_write only wrote %d\n", retval);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = BIO_write(in, signed_data, signed_data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval != signed_data_len) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("BIO_write only wrote %d\n", retval);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KRB_ERR_GENERIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = -1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7 = PKCS7_encrypt(encerts, in, cipher, flags);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (p7 == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to encrypt PKCS7 object\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = -1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch (pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7->d.enveloped->enc_data->content_type =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan OBJ_nid2obj(NID_pkcs7_signed);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REQ_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7->d.enveloped->enc_data->content_type =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan OBJ_nid2obj(NID_pkcs7_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_len = i2d_PKCS7(p7, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!*out_len || (p = *out = (unsigned char *)malloc(*out_len)) == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = i2d_PKCS7(p7, &p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("unable to write pkcs7 object\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(*out, *out_len, "/tmp/kdc_enveloped_data");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (p7 != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_free(p7);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (in != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_free(in);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (signed_data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(signed_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (enc_data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(enc_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (encerts != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_free(encerts);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancms_envelopeddata_verify(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_preauthtype pa_type,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int require_crl_checking,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *enveloped_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int enveloped_data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *data_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7 *p7 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO *out = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int size = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const unsigned char *p = enveloped_data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int tmp_buf_len = 0, tmp_buf2_len = 0, vfy_buf_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *tmp_buf = NULL, *tmp_buf2 = NULL, *vfy_buf = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int msg_type = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(enveloped_data, enveloped_data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/client_envelopeddata");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* decode received PKCS7 message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p7 = d2i_PKCS7(NULL, &p, (int)enveloped_data_len)) == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned long err = ERR_peek_error();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to decode pkcs7\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "%s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ERR_error_string(err, NULL));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* verify that the received message is PKCS7 EnvelopedData message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (OBJ_obj2nid(p7->type) != NID_pkcs7_enveloped) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Expected id-enveloped PKCS7 msg (received type = %d)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan OBJ_obj2nid(p7->type));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "wrong oid\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* decrypt received PKCS7 message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan out = BIO_new(BIO_s_mem());
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkcs7_decrypt(context, id_cryptoctx, p7, out)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("PKCS7 decryption successful\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned long err = ERR_peek_error();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (err != 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "%s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ERR_error_string(err, NULL));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("PKCS7 decryption failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* transfer the decoded PKCS7 SignedData message into a separate buffer */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (;;) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((tmp_buf = realloc(tmp_buf, size + 1024 * 10)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i = BIO_read(out, &(tmp_buf[size]), 1024 * 10);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (i <= 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size += i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tmp_buf_len = size;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(tmp_buf, tmp_buf_len, "/tmp/client_enc_keypack");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* verify PKCS7 SignedData message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch (pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan msg_type = CMS_ENVEL_SERVER;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case KRB5_PADATA_PK_AS_REP_OLD:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan msg_type = CMS_SIGN_DRAFT9;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: unrecognized pa_type = %d\n", __FUNCTION__, pa_type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * If this is the RFC style, wrap the signed data to make
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * decoding easier in the verify routine.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * For draft9-compatible, we don't do anything because it
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * is already wrapped.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef LONGHORN_BETA_COMPAT
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * The Longhorn server returns the expected RFC-style data, but
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * it is missing the sequence tag and length, so it requires
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * special processing when wrapping.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * This will hopefully be fixed before the final release and
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * this can all be removed.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (msg_type == CMS_ENVEL_SERVER || longhorn == 1) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = wrap_signeddata(tmp_buf, tmp_buf_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &tmp_buf2, &tmp_buf2_len, longhorn);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to encode signeddata\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan vfy_buf = tmp_buf2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan vfy_buf_len = tmp_buf2_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan vfy_buf = tmp_buf;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan vfy_buf_len = tmp_buf_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (msg_type == CMS_ENVEL_SERVER) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = wrap_signeddata(tmp_buf, tmp_buf_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &tmp_buf2, &tmp_buf2_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to encode signeddata\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan vfy_buf = tmp_buf2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan vfy_buf_len = tmp_buf2_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan vfy_buf = tmp_buf;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan vfy_buf_len = tmp_buf_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(vfy_buf, vfy_buf_len, "/tmp/client_enc_keypack2");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = cms_signeddata_verify(context, plg_cryptoctx, req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx, msg_type,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan require_crl_checking,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan vfy_buf, vfy_buf_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan data, data_len, NULL, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("PKCS7 Verification Success\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("PKCS7 Verification Failure\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (p7 != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_free(p7);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (out != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_free(out);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (tmp_buf != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(tmp_buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (tmp_buf2 != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(tmp_buf2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_retrieve_X509_sans(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *cert,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal **princs_ret,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal **upn_ret,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char ***dns_ret)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char buf[DN_BUF_LEN];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int p = 0, u = 0, d = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal *princs = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal *upns = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **dnss = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i, num_found = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (princs_ret == NULL && upn_ret == NULL && dns_ret == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: nowhere to return any values!\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cert == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: no certificate!\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(cert),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: looking for SANs in cert = %s\n", __FUNCTION__, buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((i = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1)) >= 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_EXTENSION *ext = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan GENERAL_NAMES *ialt = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan GENERAL_NAME *gen = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int ret = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int num_sans = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!(ext = X509_get_ext(cert, i)) || !(ialt = X509V3_EXT_d2i(ext))) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: found no subject alt name extensions\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan num_sans = sk_GENERAL_NAME_num(ialt);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: found %d subject alt name extension(s)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, num_sans);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* OK, we're likely returning something. Allocate return values */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (princs_ret != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan princs = calloc(num_sans + 1, sizeof(krb5_principal));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (princs == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (upn_ret != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan upns = calloc(num_sans + 1, sizeof(krb5_principal));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (upns == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dns_ret != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dnss = calloc(num_sans + 1, sizeof(*dnss));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dnss == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < num_sans; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data name = { 0, 0, NULL };
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gen = sk_GENERAL_NAME_value(ialt, i);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch (gen->type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case GEN_OTHERNAME:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan name.length = gen->d.otherName->value->value.sequence->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan name.data = (char *)gen->d.otherName->value->value.sequence->data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (princs != NULL
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan && OBJ_cmp(plgctx->id_pkinit_san,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gen->d.otherName->type_id) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)name.data, name.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/pkinit_san");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ret = k5int_decode_krb5_principal_name(&name, &princs[p]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ret) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed decoding pkinit san value\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan num_found++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (upns != NULL
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan && OBJ_cmp(plgctx->id_ms_san_upn,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gen->d.otherName->type_id) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ret = krb5_parse_name(context, name.data, &upns[u]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ret) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed parsing ms-upn san value\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan u++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan num_found++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: unrecognized othername oid in SAN\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case GEN_DNS:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dnss != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: found dns name = %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, gen->d.dNSName->data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dnss[d] = (unsigned char *)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan strdup((char *)gen->d.dNSName->data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dnss[d] == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed to duplicate dns name\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan d++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan num_found++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: SAN type = %d expecting %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, gen->type, GEN_OTHERNAME);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (princs)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *princs_ret = princs;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (upns)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *upn_ret = upns;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dnss)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *dns_ret = dnss;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (princs != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; princs[i] != NULL; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_principal(context, princs[i]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(princs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (upns != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; upns[i] != NULL; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_principal(context, upns[i]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(upns);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dnss != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; dnss[i] != NULL; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(dnss[i]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(dnss);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_retrieve_cert_sans(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal **princs_ret,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal **upn_ret,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char ***dns_ret)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->received_cert == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: No certificate!\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return crypto_retrieve_X509_sans(context, plgctx, reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->received_cert, princs_ret,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan upn_ret, dns_ret);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_check_cert_eku(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plgctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int checking_kdc_cert,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int allow_secondary_usage,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int *valid_eku)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char buf[DN_BUF_LEN];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int found_eku = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (valid_eku == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *valid_eku = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (reqctx->received_cert == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(reqctx->received_cert),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: looking for EKUs in cert = %s\n", __FUNCTION__, buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((i = X509_get_ext_by_NID(reqctx->received_cert,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NID_ext_key_usage, -1)) >= 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EXTENDED_KEY_USAGE *extusage;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan extusage = X509_get_ext_d2i(reqctx->received_cert, NID_ext_key_usage,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (extusage) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: found eku info in the cert\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; found_eku == 0 && i < sk_ASN1_OBJECT_num(extusage); i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OBJECT *tmp_oid;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tmp_oid = sk_ASN1_OBJECT_value(extusage, i);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: checking eku %d of %d, allow_secondary = %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, i+1, sk_ASN1_OBJECT_num(extusage),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan allow_secondary_usage);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (checking_kdc_cert) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((OBJ_cmp(tmp_oid, plgctx->id_pkinit_KPKdc) == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan || (allow_secondary_usage
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan && OBJ_cmp(tmp_oid, plgctx->id_kp_serverAuth) == 0))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan found_eku = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((OBJ_cmp(tmp_oid, plgctx->id_pkinit_KPClientAuth) == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan || (allow_secondary_usage
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan && OBJ_cmp(tmp_oid, plgctx->id_ms_kp_sc_logon) == 0))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan found_eku = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EXTENDED_KEY_USAGE_free(extusage);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (found_eku) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_BIT_STRING *usage = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: found acceptable EKU, checking for digitalSignature\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* check that digitalSignature KeyUsage is present */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((usage = X509_get_ext_d2i(reqctx->received_cert,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NID_key_usage, NULL, NULL))) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!ku_reject(reqctx->received_cert,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509v3_KU_DIGITAL_SIGNATURE)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: found digitalSignature KU\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *valid_eku = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: didn't find digitalSignature KU\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_BIT_STRING_free(usage);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning retval %d, valid_eku %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, *valid_eku);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_octetstring2key(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_enctype etype,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int dh_key_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_keyblock * key_block)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *buf = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char md[SHA_DIGEST_LENGTH];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char counter;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan size_t keybytes, keylength, offset;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data random_data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((buf = (unsigned char *) malloc(dh_key_len)) == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memset(buf, 0, dh_key_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan counter = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan offset = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan do {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan SHA_CTX c;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan SHA1_Init(&c);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan SHA1_Update(&c, &counter, 1);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan SHA1_Update(&c, key, dh_key_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan SHA1_Final(md, &c);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dh_key_len - offset < sizeof(md))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(buf + offset, md, dh_key_len - offset);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(buf + offset, md, sizeof(md));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan offset += sizeof(md);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan counter++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } while (offset < dh_key_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_block->magic = KV5M_KEYBLOCK;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_block->enctype = etype;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = krb5_c_keylengths(context, etype, &keybytes, &keylength);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_block->length = keylength;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_block->contents = calloc(keylength, sizeof(unsigned char *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (key_block->contents == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan random_data.length = keybytes;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan random_data.data = (char *)buf;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = krb5_c_random_to_key(context, etype, &random_data, key_block);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (buf != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval && key_block->contents != NULL && key_block->length != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memset(key_block->contents, 0, key_block->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_block->length = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanclient_create_dh(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int dh_size,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **dh_params,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *dh_params_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **dh_pubkey,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *dh_pubkey_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *buf = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int dh_err = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER *pub_key = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cryptoctx->dh == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((cryptoctx->dh = DH_new()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((cryptoctx->dh->g = BN_new()) == NULL ||
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (cryptoctx->dh->q = BN_new()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(dh_size) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case 1024:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("client uses 1024 DH keys\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cryptoctx->dh->p = get_rfc2409_prime_1024(NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case 2048:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("client uses 2048 DH keys\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cryptoctx->dh->p = BN_bin2bn(pkinit_2048_dhprime,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sizeof(pkinit_2048_dhprime), NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case 4096:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("client uses 4096 DH keys\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cryptoctx->dh->p = BN_bin2bn(pkinit_4096_dhprime,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sizeof(pkinit_4096_dhprime), NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_set_word((cryptoctx->dh->g), DH_GENERATOR_2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_rshift1(cryptoctx->dh->q, cryptoctx->dh->p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_generate_key(cryptoctx->dh);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_check(cryptoctx->dh, &dh_err);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dh_err != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Warning: dh_check failed with %d\n", dh_err);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dh_err & DH_CHECK_P_NOT_PRIME)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("p value is not prime\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dh_err & DH_CHECK_P_NOT_SAFE_PRIME)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("p value is not a safe prime\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dh_err & DH_UNABLE_TO_CHECK_GENERATOR)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("unable to check the generator value\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dh_err & DH_NOT_SUITABLE_GENERATOR)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("the g value is not a generator\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_DH
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_dh(cryptoctx->dh, "client's DH params\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_pubkey(cryptoctx->dh->pub_key, "client's pub_key=");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_check_pub_key(cryptoctx->dh, cryptoctx->dh->pub_key, &dh_err);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dh_err != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("dh_check_pub_key failed with %d\n", dh_err);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* pack DHparams */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* aglo: usually we could just call i2d_DHparams to encode DH params
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * however, PKINIT requires RFC3279 encoding and openssl does pkcs#3.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_encode_dh_params(cryptoctx->dh->p, cryptoctx->dh->g,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cryptoctx->dh->q, dh_params, dh_params_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* pack DH public key */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * encoding shall be used as the contents (the value) of the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * data element
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((pub_key = BN_to_ASN1_INTEGER(cryptoctx->dh->pub_key, NULL)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((buf = *dh_pubkey = (unsigned char *)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan malloc((size_t) *dh_pubkey_len)) == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_ASN1_INTEGER(pub_key, &buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pub_key != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER_free(pub_key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cryptoctx->dh != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_free(cryptoctx->dh);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cryptoctx->dh = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (*dh_params != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(*dh_params);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *dh_params = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (*dh_pubkey != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(*dh_pubkey);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *dh_pubkey = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pub_key != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER_free(pub_key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanclient_process_dh(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *subjectPublicKey_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int subjectPublicKey_length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **client_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *client_key_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIGNUM *server_pub_key = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER *pub_key = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan long data_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* decode subjectPublicKey (retrieve INTEGER from OCTET_STRING) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (der_decode_data(subjectPublicKey_data, (long)subjectPublicKey_length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &data, &data_len) != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to decode subjectPublicKey\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *client_key_len = DH_size(cryptoctx->dh);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*client_key = (unsigned char *)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan malloc((size_t) *client_key_len)) == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p = data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((pub_key = d2i_ASN1_INTEGER(NULL, &p, data_len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((server_pub_key = ASN1_INTEGER_to_BN(pub_key, NULL)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_compute_key(*client_key, server_pub_key, cryptoctx->dh);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_DH
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_pubkey(server_pub_key, "server's pub_key=");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("client secret key (%d)= ", *client_key_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer(*client_key, *client_key_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (server_pub_key != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_free(server_pub_key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pub_key != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER_free(pub_key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free (data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (*client_key != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(*client_key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *client_key = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pub_key != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER_free(pub_key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free (data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanserver_check_dh(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_octet_data *dh_params,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int minbits)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH *dh = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *tmp = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int dh_prime_bits;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tmp = dh_params->data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh = DH_new();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh = pkinit_decode_dh_params(&dh, &tmp, dh_params->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dh == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to decode dhparams\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* KDC SHOULD check to see if the key parameters satisfy its policy */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh_prime_bits = BN_num_bits(dh->p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (minbits && dh_prime_bits < minbits) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("client sent dh params with %d bits, we require %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh_prime_bits, minbits);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* check dhparams is group 2 */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_check_dh_params(cryptoctx->dh_1024->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh->p, dh->g, dh->q) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* check dhparams is group 14 */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_check_dh_params(cryptoctx->dh_2048->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh->p, dh->g, dh->q) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* check dhparams is group 16 */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_check_dh_params(cryptoctx->dh_4096->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh->p, dh->g, dh->q) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_cryptoctx->dh = dh;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_free(dh);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* kdc's dh function */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanserver_process_dh(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **dh_pubkey,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *dh_pubkey_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **server_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *server_key_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KRB_ERR_GENERIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH *dh = NULL, *dh_server = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER *pub_key = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* get client's received DH parameters that we saved in server_check_dh */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh = cryptoctx->dh;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh_server = DH_new();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dh_server == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh_server->p = BN_dup(dh->p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh_server->g = BN_dup(dh->g);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh_server->q = BN_dup(dh->q);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* decode client's public key */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p = data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pub_key = d2i_ASN1_INTEGER(NULL, (const unsigned char **)&p, (int)data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pub_key == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh->pub_key = ASN1_INTEGER_to_BN(pub_key, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dh->pub_key == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER_free(pub_key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!DH_generate_key(dh_server))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* generate DH session key */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *server_key_len = DH_size(dh_server);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_compute_key(*server_key, dh->pub_key, dh_server);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_DH
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_dh(dh_server, "client&server's DH params\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_pubkey(dh->pub_key, "client's pub_key=");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_pubkey(dh_server->pub_key, "server's pub_key=");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("server secret key=");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer(*server_key, *server_key_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* KDC reply */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* pack DH public key */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * encoding shall be used as the contents (the value) of the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * data element
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((pub_key = BN_to_ASN1_INTEGER(dh_server->pub_key, NULL)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_ASN1_INTEGER(pub_key, &p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pub_key != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER_free(pub_key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dh_server != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_free(dh_server);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dh_server != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_free(dh_server);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (*dh_pubkey != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(*dh_pubkey);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (*server_key != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(*server_key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan/*
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan * Solaris Kerberos:
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan * Add locking around did_init to make it MT-safe.
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan */
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanopenssl_init()
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan krb5_error_code ret = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan static int did_init = 0;
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan static k5_mutex_t init_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan ret = k5_mutex_lock(&init_mutex);
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan if (ret == 0) {
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan if (!did_init) {
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan /* initialize openssl routines */
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan CRYPTO_malloc_init();
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan ERR_load_crypto_strings();
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan OpenSSL_add_all_algorithms();
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan did_init++;
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan }
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan k5_mutex_unlock(&init_mutex);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan return (ret);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_encode_dh_params(BIGNUM *p, BIGNUM *g, BIGNUM *q,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **buf, unsigned int *buf_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int bufsize = 0, r = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *tmp = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER *ap = NULL, *ag = NULL, *aq = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((ap = BN_to_ASN1_INTEGER(p, NULL)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((ag = BN_to_ASN1_INTEGER(g, NULL)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((aq = BN_to_ASN1_INTEGER(q, NULL)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan bufsize = i2d_ASN1_INTEGER(ap, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan bufsize += i2d_ASN1_INTEGER(ag, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan bufsize += i2d_ASN1_INTEGER(aq, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = ASN1_object_size(1, bufsize, V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tmp = *buf = (unsigned char *)malloc((size_t) r);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (tmp == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&tmp, 1, bufsize, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_ASN1_INTEGER(ap, &tmp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_ASN1_INTEGER(ag, &tmp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_ASN1_INTEGER(aq, &tmp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *buf_len = r;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ap != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER_free(ap);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ag != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER_free(ag);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (aq != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER_free(aq);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic DH *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_decode_dh_params(DH ** a, unsigned char **pp, unsigned int len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER ai, *aip = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan long length = (long) len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_D2I_vars(a, DH *, DH_new);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_D2I_Init();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_D2I_start_sequence();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan aip = &ai;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ai.data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ai.length = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (aip == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*a)->p = ASN1_INTEGER_to_BN(aip, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*a)->p == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ai.data != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan OPENSSL_free(ai.data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ai.data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ai.length = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (aip == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*a)->g = ASN1_INTEGER_to_BN(aip, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*a)->g == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ai.data != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan OPENSSL_free(ai.data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ai.data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ai.length = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (aip == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*a)->q = ASN1_INTEGER_to_BN(aip, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*a)->q == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ai.data != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan OPENSSL_free(ai.data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ai.data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ai.length = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_D2I_end_sequence();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_D2I_Finish(a, DH_free, 0);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_create_sequence_of_principal_identifiers(
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int type,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data **out_data)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KRB_ERR_GENERIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_external_principal_identifier **krb5_trusted_certifiers = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *td_certifiers = NULL, *data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_typed_data **typed_data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case TD_TRUSTED_CERTIFIERS:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = create_krb5_trustedCertifiers(context, plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("create_krb5_trustedCertifiers failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case TD_INVALID_CERTIFICATES:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = create_krb5_invalidCertificates(context, plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("create_krb5_invalidCertificates failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = -1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_td_trusted_certifiers((const krb5_external_principal_identifier **)krb5_trusted_certifiers, &td_certifiers);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("encode_krb5_td_trusted_certifiers failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)td_certifiers->data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan td_certifiers->length, "/tmp/kdc_td_certifiers");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan typed_data = malloc (2 * sizeof(krb5_typed_data *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (typed_data == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan typed_data[1] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan init_krb5_typed_data(&typed_data[0]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (typed_data[0] == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan typed_data[0]->type = type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan typed_data[0]->length = td_certifiers->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan typed_data[0]->data = (unsigned char *)td_certifiers->data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_typed_data((const krb5_typed_data **)typed_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("encode_krb5_typed_data failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)data->data, data->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/kdc_edata");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_data = (krb5_data *)malloc(sizeof(krb5_data));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*out_data)->length = data->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*out_data)->data = (char *)malloc(data->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy((*out_data)->data, data->data, data->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_trusted_certifiers != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_external_principal_identifier(&krb5_trusted_certifiers);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (data != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (data->data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(data->data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (td_certifiers != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(td_certifiers);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (typed_data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_typed_data(&typed_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_create_td_trusted_certifiers(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data **out_data)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KRB_ERR_GENERIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_create_sequence_of_principal_identifiers(context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plg_cryptoctx, req_cryptoctx, id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan TD_TRUSTED_CERTIFIERS, out_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_create_td_invalid_certificate(
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data **out_data)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KRB_ERR_GENERIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_create_sequence_of_principal_identifiers(context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plg_cryptoctx, req_cryptoctx, id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan TD_INVALID_CERTIFICATES, out_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_create_td_dh_parameters(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_opts *opts,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data **out_data)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KRB_ERR_GENERIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int buf1_len = 0, buf2_len = 0, buf3_len = 0, i = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_typed_data **typed_data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *data = NULL, *encoded_algId = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_algorithm_identifier **algId = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (opts->dh_min_bits > 4096) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (opts->dh_min_bits <= 1024) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_encode_dh_params(plg_cryptoctx->dh_1024->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plg_cryptoctx->dh_1024->g, plg_cryptoctx->dh_1024->q,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &buf1, &buf1_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (opts->dh_min_bits <= 2048) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_encode_dh_params(plg_cryptoctx->dh_2048->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plg_cryptoctx->dh_2048->g, plg_cryptoctx->dh_2048->q,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &buf2, &buf2_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_encode_dh_params(plg_cryptoctx->dh_4096->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plg_cryptoctx->dh_4096->g, plg_cryptoctx->dh_4096->q,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &buf3, &buf3_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (opts->dh_min_bits <= 1024) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId = malloc(4 * sizeof(krb5_algorithm_identifier *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[3] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId[0] == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0]->parameters.data = (unsigned char *)malloc(buf2_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId[0]->parameters.data == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(algId[0]->parameters.data, buf2, buf2_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0]->parameters.length = buf2_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0]->algorithm = dh_oid;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[1] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId[1] == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[1]->parameters.data = (unsigned char *)malloc(buf3_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId[1]->parameters.data == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(algId[1]->parameters.data, buf3, buf3_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[1]->parameters.length = buf3_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[1]->algorithm = dh_oid;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[2] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId[2] == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[2]->parameters.data = (unsigned char *)malloc(buf1_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId[2]->parameters.data == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(algId[2]->parameters.data, buf1, buf1_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[2]->parameters.length = buf1_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[2]->algorithm = dh_oid;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (opts->dh_min_bits <= 2048) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId = malloc(3 * sizeof(krb5_algorithm_identifier *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[2] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId[0] == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0]->parameters.data = (unsigned char *)malloc(buf2_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId[0]->parameters.data == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(algId[0]->parameters.data, buf2, buf2_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0]->parameters.length = buf2_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0]->algorithm = dh_oid;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[1] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId[1] == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[1]->parameters.data = (unsigned char *)malloc(buf3_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId[1]->parameters.data == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(algId[1]->parameters.data, buf3, buf3_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[1]->parameters.length = buf3_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[1]->algorithm = dh_oid;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (opts->dh_min_bits <= 4096) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId = malloc(2 * sizeof(krb5_algorithm_identifier *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[1] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId[0] == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0]->parameters.data = (unsigned char *)malloc(buf3_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId[0]->parameters.data == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(algId[0]->parameters.data, buf3, buf3_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0]->parameters.length = buf3_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0]->algorithm = dh_oid;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_td_dh_parameters((const krb5_algorithm_identifier **)algId, &encoded_algId);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)encoded_algId->data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encoded_algId->length, "/tmp/kdc_td_dh_params");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan typed_data = malloc (2 * sizeof(krb5_typed_data *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (typed_data == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan typed_data[1] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan init_krb5_typed_data(&typed_data[0]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (typed_data == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan typed_data[0]->type = TD_DH_PARAMETERS;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan typed_data[0]->length = encoded_algId->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan typed_data[0]->data = (unsigned char *)encoded_algId->data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_typed_data((const krb5_typed_data**)typed_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("encode_krb5_typed_data failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_ASN1
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)data->data, data->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "/tmp/kdc_edata");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_data = (krb5_data *)malloc(sizeof(krb5_data));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (*out_data == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*out_data)->length = data->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*out_data)->data = (char *)malloc(data->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*out_data)->data == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(*out_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy((*out_data)->data, data->data, data->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (buf1 != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(buf1);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (buf2 != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(buf2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (buf3 != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(buf3);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (data != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (data->data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(data->data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (typed_data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_typed_data(&typed_data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (encoded_algId != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(encoded_algId);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan while(algId[i] != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId[i]->parameters.data != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(algId[i]->parameters.data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(algId[i]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(algId);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_check_kdc_pkid(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *pdid_buf,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int pkid_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int *valid_kdcPkId)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_ISSUER_AND_SERIAL *is = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const unsigned char *p = pdid_buf;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int status = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *kdc_cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *valid_kdcPkId = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("found kdcPkId in AS REQ\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan is = d2i_PKCS7_ISSUER_AND_SERIAL(NULL, &p, (int)pkid_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (is == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan status = X509_NAME_cmp(X509_get_issuer_name(kdc_cert), is->issuer);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!status) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan status = ASN1_INTEGER_cmp(X509_get_serialNumber(kdc_cert), is->serial);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!status)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *valid_kdcPkId = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_free(is->issuer);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER_free(is->serial);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(is);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_check_dh_params(BIGNUM * p1, BIGNUM * p2, BIGNUM * g1, BIGNUM * q1)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIGNUM *g2 = NULL, *q2 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!BN_cmp(p1, p2)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan g2 = BN_new();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_set_word(g2, DH_GENERATOR_2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!BN_cmp(g1, g2)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan q2 = BN_new();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_rshift1(q2, p1);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!BN_cmp(q1, q2)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("good %d dhparams\n", BN_num_bits(p1));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("bad group 2 q dhparameter\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_free(q2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("bad g dhparameter\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_free(g2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("p is not well-known group 2 dhparameter\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_process_td_dh_params(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_algorithm_identifier **algId,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int *new_dh_size)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i = 0, use_sent_dh = 0, ok = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("dh parameters\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan while (algId[i] != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH *dh = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *tmp = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int dh_prime_bits = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId[i]->algorithm.length != dh_oid.length ||
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan memcmp(algId[i]->algorithm.data, dh_oid.data, dh_oid.length))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tmp = algId[i]->parameters.data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh = DH_new();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh = pkinit_decode_dh_params(&dh, &tmp, algId[i]->parameters.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh_prime_bits = BN_num_bits(dh->p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("client sent %d DH bits server prefers %d DH bits\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *new_dh_size, dh_prime_bits);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(dh_prime_bits) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case 1024:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_check_dh_params(cryptoctx->dh_1024->p, dh->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh->g, dh->q) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *new_dh_size = 1024;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ok = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case 2048:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_check_dh_params(cryptoctx->dh_2048->p, dh->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh->g, dh->q) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *new_dh_size = 2048;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ok = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case 4096:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_check_dh_params(cryptoctx->dh_4096->p, dh->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh->g, dh->q) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *new_dh_size = 4096;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ok = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!ok) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_check(dh, &retval);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("DH parameters provided by server are unacceptable\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan use_sent_dh = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ok = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!use_sent_dh)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_free(dh);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ok) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (req_cryptoctx->dh != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_free(req_cryptoctx->dh);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_cryptoctx->dh = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (use_sent_dh)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_cryptoctx->dh = dh;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ok)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanopenssl_callback(int ok, X509_STORE_CTX * ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!ok) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char buf[DN_BUF_LEN];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("cert = %s\n", buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("callback function: %d (%s)\n", ctx->error,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_verify_cert_error_string(ctx->error));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ok;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanopenssl_callback_ignore_crls(int ok, X509_STORE_CTX * ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!ok) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch (ctx->error) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case X509_V_ERR_UNABLE_TO_GET_CRL:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ok;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic ASN1_OBJECT *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int nid;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch (pkcs7_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CMS_SIGN_CLIENT:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return cryptoctx->id_pkinit_authData;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CMS_SIGN_DRAFT9:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Delay creating this OID until we know we need it.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * It shadows an existing OpenSSL oid. If it
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * is created too early, it breaks things like
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * the use of pkcs12 (which uses pkcs7 structures).
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * We need this shadow version because our code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * depends on the "other" type to be unknown to the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * OpenSSL code.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cryptoctx->id_pkinit_authData9 == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Creating shadow instance of pkcs7-data oid\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nid = OBJ_create("1.2.840.113549.1.7.1", "id-pkcs7-data",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "PKCS7 data");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (nid == NID_undef)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cryptoctx->id_pkinit_authData9 = OBJ_nid2obj(nid);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return cryptoctx->id_pkinit_authData9;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CMS_SIGN_SERVER:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return cryptoctx->id_pkinit_DHKeyData;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CMS_ENVEL_SERVER:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return cryptoctx->id_pkinit_rkeyData;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef LONGHORN_BETA_COMPAT
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#if 0
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * This is a version that worked with Longhorn Beta 3.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanwrap_signeddata(unsigned char *data, unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **out, unsigned int *out_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int is_longhorn_server)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int orig_len = 0, oid_len = 0, tot_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OBJECT *oid = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: This is the Longhorn version and is_longhorn_server = %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, is_longhorn_server);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Get length to wrap the original data with SEQUENCE tag */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tot_len = orig_len = ASN1_object_size(1, (int)data_len, V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (is_longhorn_server == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Add the signedData OID and adjust lengths */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan oid = OBJ_nid2obj(NID_pkcs7_signed);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan oid_len = i2d_ASN1_OBJECT(oid, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tot_len = ASN1_object_size(1, (int)(orig_len+oid_len), V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p = *out = (unsigned char *)malloc(tot_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (p == NULL) return -1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (is_longhorn_server == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&p, 1, (int)(orig_len+oid_len),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_ASN1_OBJECT(oid, &p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&p, 1, (int)data_len, 0, V_ASN1_CONTEXT_SPECIFIC);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&p, 1, (int)data_len, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan memcpy(p, data, data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_len = tot_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * This is a version that works with a patched Longhorn KDC.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * (Which should match SP1 ??).
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanwrap_signeddata(unsigned char *data, unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **out, unsigned int *out_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int is_longhorn_server)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int oid_len = 0, tot_len = 0, wrap_len = 0, tag_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OBJECT *oid = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: This is the Longhorn version and is_longhorn_server = %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, is_longhorn_server);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* New longhorn is missing another sequence */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (is_longhorn_server == 1)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan wrap_len = ASN1_object_size(1, (int)(data_len), V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan wrap_len = data_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Get length to wrap the original data with SEQUENCE tag */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tag_len = ASN1_object_size(1, (int)wrap_len, V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Always add oid */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan oid = OBJ_nid2obj(NID_pkcs7_signed);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan oid_len = i2d_ASN1_OBJECT(oid, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan oid_len += tag_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tot_len = ASN1_object_size(1, (int)(oid_len), V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p = *out = (unsigned char *)malloc(tot_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (p == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return -1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&p, 1, (int)(oid_len),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_ASN1_OBJECT(oid, &p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&p, 1, (int)wrap_len, 0, V_ASN1_CONTEXT_SPECIFIC);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Wrap in extra seq tag */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (is_longhorn_server == 1) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&p, 1, (int)data_len, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(p, data, data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_len = tot_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanwrap_signeddata(unsigned char *data, unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **out, unsigned int *out_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int orig_len = 0, oid_len = 0, tot_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OBJECT *oid = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Get length to wrap the original data with SEQUENCE tag */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tot_len = orig_len = ASN1_object_size(1, (int)data_len, V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Add the signedData OID and adjust lengths */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan oid = OBJ_nid2obj(NID_pkcs7_signed);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan oid_len = i2d_ASN1_OBJECT(oid, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tot_len = ASN1_object_size(1, (int)(orig_len+oid_len), V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p = *out = (unsigned char *)malloc(tot_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (p == NULL) return -1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&p, 1, (int)(orig_len+oid_len),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_ASN1_OBJECT(oid, &p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&p, 1, (int)data_len, 0, V_ASN1_CONTEXT_SPECIFIC);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(p, data, data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_len = tot_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanprepare_enc_data(unsigned char *indata,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int indata_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **outdata,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int *outdata_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_const_CTX c;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan long length = indata_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int Ttag, Tclass;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan long Tlen;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan c.pp = (const unsigned char **)&indata;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan c.q = *(const unsigned char **)&indata;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan c.error = ERR_R_NESTED_ASN1_ERROR;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan c.p= *(const unsigned char **)&indata;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan c.max = (length == 0)?0:(c.p+length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan asn1_GetSequence(&c,&length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan c.p += Tlen;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan asn1_const_Finish(&c);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *outdata = (unsigned char *)malloc((size_t)Tlen);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (outdata == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(*outdata, c.p, (size_t)Tlen);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *outdata_len = Tlen;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_C_LoadModule(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan void *handle;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_RV (*getflist)(CK_FUNCTION_LIST_PTR_PTR);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("loading module \"%s\"... ", modname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan handle = dlopen(modname, RTLD_NOW | RTLD_GROUP);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (handle == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("not found\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan getflist = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR)) dlsym(handle, "C_GetFunctionList");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (getflist == NULL || (*getflist)(p11p) != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) dlclose(handle);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("ok\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return handle;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic CK_RV
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_C_UnloadModule(void *handle)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dlclose(handle) != 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return CKR_GENERAL_ERROR;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return CKR_OK;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_login(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_TOKEN_INFO *tip)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data rdat;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *prompt;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int prompt_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_prompt kprompt;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_prompt_type prompt_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int r = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (tip->flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rdat.data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rdat.length = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
011f53d9b9cd056c852c11fd6017d6af580019e9Will Fiveash unsigned char *lastnonwspc, *iterp; /* Solaris Kerberos - trim token label */
011f53d9b9cd056c852c11fd6017d6af580019e9Will Fiveash int count;
ee0dcaba237cc9f9f74e030221a847cb76a4895eWill Fiveash
ee0dcaba237cc9f9f74e030221a847cb76a4895eWill Fiveash if (!id_cryptoctx->prompter) {
ee0dcaba237cc9f9f74e030221a847cb76a4895eWill Fiveash pkiDebug("pkinit_login: id_cryptoctx->prompter is NULL\n");
ee0dcaba237cc9f9f74e030221a847cb76a4895eWill Fiveash /* Solaris Kerberos: Improved error messages */
ee0dcaba237cc9f9f74e030221a847cb76a4895eWill Fiveash krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
ee0dcaba237cc9f9f74e030221a847cb76a4895eWill Fiveash gettext("failed to log into token: prompter function is NULL"));
ee0dcaba237cc9f9f74e030221a847cb76a4895eWill Fiveash return (KRB5KDC_ERR_PREAUTH_FAILED);
ee0dcaba237cc9f9f74e030221a847cb76a4895eWill Fiveash }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos - Changes for gettext() */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan prompt_len = sizeof (tip->label) + 256;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((prompt = (char *) malloc(prompt_len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
011f53d9b9cd056c852c11fd6017d6af580019e9Will Fiveash
011f53d9b9cd056c852c11fd6017d6af580019e9Will Fiveash /* Solaris Kerberos - trim token label which can be padded with space */
011f53d9b9cd056c852c11fd6017d6af580019e9Will Fiveash for (count = 0, iterp = tip->label; count < sizeof (tip->label);
011f53d9b9cd056c852c11fd6017d6af580019e9Will Fiveash count++, iterp++) {
011f53d9b9cd056c852c11fd6017d6af580019e9Will Fiveash if ((char) *iterp != ' ')
011f53d9b9cd056c852c11fd6017d6af580019e9Will Fiveash lastnonwspc = iterp;
011f53d9b9cd056c852c11fd6017d6af580019e9Will Fiveash }
011f53d9b9cd056c852c11fd6017d6af580019e9Will Fiveash (void) snprintf(prompt, prompt_len, gettext("%.*s PIN"),
011f53d9b9cd056c852c11fd6017d6af580019e9Will Fiveash (int) (lastnonwspc - tip->label) + 1, tip->label);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (tip->flags & CKF_USER_PIN_LOCKED)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) strlcat(prompt, gettext(" (Warning: PIN locked)"), prompt_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else if (tip->flags & CKF_USER_PIN_FINAL_TRY)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) strlcat(prompt, gettext(" (Warning: PIN final try)"), prompt_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else if (tip->flags & CKF_USER_PIN_COUNT_LOW)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) strlcat(prompt, gettext(" (Warning: PIN count low)"), prompt_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rdat.data = (char *)malloc(tip->ulMaxPinLen + 2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rdat.length = tip->ulMaxPinLen + 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kprompt.prompt = prompt;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kprompt.hidden = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kprompt.reply = &rdat;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan prompt_type = KRB5_PROMPT_TYPE_PREAUTH;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* PROMPTER_INVOCATION */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan k5int_set_prompt_types(context, &prompt_type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL, NULL, 1, &kprompt);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan k5int_set_prompt_types(context, 0);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(prompt);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_Login(id_cryptoctx->session, CKU_USER,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (u_char *) rdat.data, rdat.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_Login: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to log into token: %s"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = KRB5KDC_ERR_PREAUTH_FAILED;
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash } else {
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash /* Solaris Kerberos: only need to login once */
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash id_cryptoctx->p11flags |= C_LOGIN_DONE;
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rdat.data)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(rdat.data);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return r;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_open_session(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context cctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i, r;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *cp;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_ULONG count = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_SLOT_ID_PTR slotlist;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_TOKEN_INFO tinfo;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cctx->p11_module != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0; /* session already open */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Load module */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cctx->p11_module =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_C_LoadModule(cctx->p11_module_name, &cctx->p11);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cctx->p11_module == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Init */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Don't fail if cryptoki is already initialized */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = cctx->p11->C_Initialize(NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r != CKR_OK && r != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_Initialize: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Solaris Kerberos:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * If C_Initialize was already called by the process before the pkinit
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * module was loaded then record that fact.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * "finalize_pkcs11" is used by pkinit_fini_pkcs11 to determine whether
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * or not C_Finalize() should be called.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cctx->finalize_pkcs11 =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (r == CKR_CRYPTOKI_ALREADY_INITIALIZED ? FALSE : TRUE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Get the list of available slots */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cctx->slotid != PK_NOSLOT) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* A slot was specified, so that's the only one in the list */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan count = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan slotlist = (CK_SLOT_ID_PTR) malloc(sizeof (CK_SLOT_ID));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan slotlist[0] = cctx->slotid;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cctx->p11->C_GetSlotList(TRUE, NULL, &count) != CKR_OK)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (count == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan slotlist = (CK_SLOT_ID_PTR) malloc(count * sizeof (CK_SLOT_ID));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cctx->p11->C_GetSlotList(TRUE, slotlist, &count) != CKR_OK)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Look for the given token label, or if none given take the first one */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < count; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Open session */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = cctx->p11->C_OpenSession(slotlist[i], CKF_SERIAL_SESSION,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL, NULL, &cctx->session)) != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_OpenSession: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Get token info */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = cctx->p11->C_GetTokenInfo(slotlist[i], &tinfo)) != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_GetTokenInfo: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (cp = tinfo.label + sizeof (tinfo.label) - 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *cp == '\0' || *cp == ' '; cp--)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *cp = '\0';
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("open_session: slotid %d token \"%s\"\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int) slotlist[i], tinfo.label);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cctx->token_label == NULL ||
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan !strcmp((char *) cctx->token_label, (char *) tinfo.label))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cctx->p11->C_CloseSession(cctx->session);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (i >= count) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(slotlist);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("open_session: no matching token found\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cctx->slotid = slotlist[i];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(slotlist);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("open_session: slotid %d (%d of %d)\n", (int) cctx->slotid,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i + 1, (int) count);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Login if needed */
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash /* Solaris Kerberos: added cctx->p11flags check */
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash if (tinfo.flags & CKF_LOGIN_REQUIRED && ! (cctx->p11flags & C_LOGIN_DONE))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = pkinit_login(context, cctx, &tinfo);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return r;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Look for a key that's:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * 1. private
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * 2. capable of the specified operation (usually signing or decrypting)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * 3. RSA (this may be wrong but it's all we can do for now)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * 4. matches the id of the cert we chose
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * You must call pkinit_get_certs before calling pkinit_find_private_key
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * (that's because we need the ID of the private key)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * pkcs11 says the id of the key doesn't have to match that of the cert, but
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * I can't figure out any other way to decide which key to use.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * We should only find one key that fits all the requirements.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * If there are more than one, we just take the first one.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_ATTRIBUTE_TYPE usage,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_OBJECT_HANDLE *objp)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_OBJECT_CLASS cls;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_ATTRIBUTE attrs[4];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_ULONG count;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_KEY_TYPE keytype;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int nattrs = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int r;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef PKINIT_USE_KEY_USAGE
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_BBOOL true_false;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cls = CKO_PRIVATE_KEY;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].type = CKA_CLASS;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].pValue = &cls;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].ulValueLen = sizeof cls;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nattrs++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef PKINIT_USE_KEY_USAGE
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Some cards get confused if you try to specify a key usage,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * so don't, and hope for the best. This will fail if you have
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * several keys with the same id and different usages but I have
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * not seen this on real cards.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan true_false = TRUE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].type = usage;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].pValue = &true_false;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].ulValueLen = sizeof true_false;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nattrs++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan keytype = CKK_RSA;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].type = CKA_KEY_TYPE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].pValue = &keytype;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].ulValueLen = sizeof keytype;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nattrs++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].type = CKA_ID;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].pValue = id_cryptoctx->cert_id;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].ulValueLen = id_cryptoctx->cert_id_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nattrs++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("found %d private keys (%s)\n", (int) count, pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Solaris Kerberos:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * The CKA_ID may not be correctly set for the private key. For e.g. when
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * storing a private key in softtoken pktool(1) doesn't generate or store
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * a CKA_ID for the private key. Another way to identify the private key is
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * to look for a private key with the same RSA modulus as the public key
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * in the certificate.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r == CKR_OK && count != 1) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_PKEY *priv;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *cert;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int n_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *n_bytes;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cert = sk_X509_value(id_cryptoctx->my_certs, 0);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan priv = X509_get_pubkey(cert);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (priv == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Failed to extract pub key from cert\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nattrs = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cls = CKO_PRIVATE_KEY;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].type = CKA_CLASS;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].pValue = &cls;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].ulValueLen = sizeof cls;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nattrs++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef PKINIT_USE_KEY_USAGE
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan true_false = TRUE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].type = usage;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].pValue = &true_false;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].ulValueLen = sizeof true_false;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nattrs++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan keytype = CKK_RSA;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].type = CKA_KEY_TYPE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].pValue = &keytype;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].ulValueLen = sizeof keytype;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nattrs++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan n_len = BN_num_bytes(priv->pkey.rsa->n);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan n_bytes = (unsigned char *) malloc((size_t) n_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (n_bytes == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (ENOMEM);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (BN_bn2bin(priv->pkey.rsa->n, n_bytes) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free (n_bytes);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("zero-byte key modulus\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].type = CKA_MODULUS;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].ulValueLen = n_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].pValue = n_bytes;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nattrs++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free (n_bytes);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("found %d private keys (%s)\n", (int) count, pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r != CKR_OK || count < 1)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_decode_data_fs(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **decoded_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *decoded_data_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (decode_data(decoded_data, decoded_data_len, data, data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->my_key, sk_X509_value(id_cryptoctx->my_certs,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->cert_index)) <= 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to decode data\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef SILLYDECRYPT
159d09a20817016f09b3ea28d1bdada4a336bb91Mark PhalanCK_RV
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_C_Decrypt(pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_BYTE_PTR pEncryptedData,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_ULONG ulEncryptedDataLen,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_BYTE_PTR pData,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_ULONG_PTR pulDataLen)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_RV rv = CKR_OK;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rv = id_cryptoctx->p11->C_Decrypt(id_cryptoctx->session, pEncryptedData,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ulEncryptedDataLen, pData, pulDataLen);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (rv == CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pData %x *pulDataLen %d\n", (int) pData, (int) *pulDataLen);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return rv;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_decode_data_pkcs11(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **decoded_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *decoded_data_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_OBJECT_HANDLE obj;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_ULONG len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_MECHANISM mech;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *cp;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int r;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_open_session(context, id_cryptoctx)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("can't open pkcs11 session\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash /* Solaris Kerberos: Login, if needed, to access private object */
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash if (!(id_cryptoctx->p11flags & C_LOGIN_DONE)) {
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash CK_TOKEN_INFO tinfo;
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash r = id_cryptoctx->p11->C_GetTokenInfo(id_cryptoctx->slotid, &tinfo);
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash if (r != 0)
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash return r;
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash r = pkinit_login(context, id_cryptoctx, &tinfo);
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash if (r != 0)
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash return r;
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash }
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = pkinit_find_private_key(id_cryptoctx, CKA_DECRYPT, &obj);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r != 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return r;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan mech.mechanism = CKM_RSA_PKCS;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan mech.pParameter = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan mech.ulParameterLen = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_DecryptInit(id_cryptoctx->session, &mech,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan obj)) != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_DecryptInit: 0x%x\n", (int) r);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("data_len = %d\n", data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cp = (unsigned char *)malloc((size_t) data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cp == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = data_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef SILLYDECRYPT
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("session %x edata %x edata_len %d data %x datalen @%x %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int) id_cryptoctx->session, (int) data, (int) data_len, (int) cp,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int) &len, (int) len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = pkinit_C_Decrypt(id_cryptoctx, data, (CK_ULONG) data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cp, &len)) != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_Decrypt(id_cryptoctx->session, data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (CK_ULONG) data_len, cp, &len)) != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_Decrypt: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r == CKR_BUFFER_TOO_SMALL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("decrypt %d needs %d\n", (int) data_len, (int) len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("decrypt %d -> %d\n", (int) data_len, (int) len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *decoded_data_len = len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *decoded_data = cp;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_decode_data(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **decoded_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *decoded_data_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->pkcs11_method != 1)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_decode_data_fs(context, id_cryptoctx, data, data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan decoded_data, decoded_data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_decode_data_pkcs11(context, id_cryptoctx, data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan data_len, decoded_data, decoded_data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_sign_data_fs(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **sig,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *sig_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (create_signature(sig, sig_len, data, data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->my_key) != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to create the signature\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_sign_data_pkcs11(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **sig,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *sig_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_OBJECT_HANDLE obj;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_ULONG len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_MECHANISM mech;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *cp;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int r;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_open_session(context, id_cryptoctx)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("can't open pkcs11 session\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash /* Solaris Kerberos: Login, if needed, to access private object */
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash if (!(id_cryptoctx->p11flags & C_LOGIN_DONE)) {
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash CK_TOKEN_INFO tinfo;
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash r = id_cryptoctx->p11->C_GetTokenInfo(id_cryptoctx->slotid, &tinfo);
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash if (r != 0)
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash return r;
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash r = pkinit_login(context, id_cryptoctx, &tinfo);
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash if (r != 0)
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash return r;
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash }
7d2d870ed78c1c0b10f15787cf9a400bb0b28fdaWill Fiveash
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = pkinit_find_private_key(id_cryptoctx, CKA_SIGN, &obj);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r != 0 )
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return r;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan mech.mechanism = id_cryptoctx->mech;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan mech.pParameter = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan mech.ulParameterLen = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_SignInit(id_cryptoctx->session, &mech,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan obj)) != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_SignInit: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Key len would give an upper bound on sig size, but there's no way to
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * get that. So guess, and if it's too small, re-malloc.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = PK_SIGLEN_GUESS;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cp = (unsigned char *)malloc((size_t) len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cp == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_Sign(id_cryptoctx->session, data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (CK_ULONG) data_len, cp, &len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r == CKR_BUFFER_TOO_SMALL || (r == CKR_OK && len >= PK_SIGLEN_GUESS)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(cp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_Sign realloc %d\n", (int) len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cp = (unsigned char *)malloc((size_t) len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_Sign(id_cryptoctx->session, data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (CK_ULONG) data_len, cp, &len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_Sign: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("sign %d -> %d\n", (int) data_len, (int) len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *sig_len = len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *sig = cp;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_sign_data(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **sig,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *sig_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx == NULL || id_cryptoctx->pkcs11_method != 1)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_sign_data_fs(context, id_cryptoctx, data, data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sig, sig_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_sign_data_pkcs11(context, id_cryptoctx, data, data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sig, sig_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalandecode_data(unsigned char **out_data, unsigned int *out_data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data, unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_PKEY *pkey, X509 *cert)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *buf = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int buf_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (out_data == NULL || out_data_len == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cert && !X509_check_private_key(cert, pkey)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("private key does not match certificate\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan buf_len = EVP_PKEY_size(pkey);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan buf = (unsigned char *)malloc((size_t) buf_len + 10);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (buf == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = EVP_PKEY_decrypt(buf, data, (int)data_len, pkey);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (len <= 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("unable to decrypt received data (len=%d)\n", data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KRB_ERR_GENERIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_data = buf;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_data_len = len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancreate_signature(unsigned char **sig, unsigned int *sig_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data, unsigned int data_len, EVP_PKEY *pkey)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_MD_CTX md_ctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkey == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_VerifyInit(&md_ctx, EVP_sha1());
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_SignUpdate(&md_ctx, data, data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *sig_len = EVP_PKEY_size(pkey);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*sig = (unsigned char *) malloc((size_t) *sig_len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_SignFinal(&md_ctx, *sig, sig_len, pkey);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_MD_CTX_cleanup(&md_ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Note:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * This is not the routine the KDC uses to get its certificate.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * This routine is intended to be called by the client
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * to obtain the KDC's certificate from some local storage
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * to be sent as a hint in its request to the KDC.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_get_kdc_cert(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal princ)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (req_cryptoctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_cryptoctx->received_cert = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_get_certs_pkcs12(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_opts *idopts,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal princ)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *x = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS12 *p12 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int ret;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan FILE *fp;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_PKEY *y = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idopts->cert_filename == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to get certificate location"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed to get user's cert location\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idopts->key_filename == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to get private key location"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed to get user's private key location\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan fp = fopen(idopts->cert_filename, "rb");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (fp == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to open PKCS12 file '%s': %s"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan idopts->cert_filename, error_message(errno));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Failed to open PKCS12 file '%s', error %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan idopts->cert_filename, errno);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p12 = d2i_PKCS12_fp(fp, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) fclose(fp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (p12 == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to decode PKCS12 file '%s' contents"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan idopts->cert_filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Failed to decode PKCS12 file '%s' contents\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan idopts->cert_filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Try parsing with no pass phrase first. If that fails,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * prompt for the pass phrase and try again.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ret = PKCS12_parse(p12, NULL, &y, &x, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ret == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data rdat;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_prompt kprompt;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_prompt_type prompt_type;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int r = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char prompt_string[128];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char prompt_reply[128];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *prompt_prefix = gettext("Pass phrase for");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Initial PKCS12_parse with no password failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memset(prompt_reply, '\0', sizeof(prompt_reply));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rdat.data = prompt_reply;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rdat.length = sizeof(prompt_reply);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = snprintf(prompt_string, sizeof(prompt_string), "%s %s",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan prompt_prefix, idopts->cert_filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r >= sizeof(prompt_string)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Prompt string, '%s %s', is too long!\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan prompt_prefix, idopts->cert_filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kprompt.prompt = prompt_string;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kprompt.hidden = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan kprompt.reply = &rdat;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan prompt_type = KRB5_PROMPT_TYPE_PREAUTH;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* PROMPTER_INVOCATION */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan k5int_set_prompt_types(context, &prompt_type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL, NULL, 1, &kprompt);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan k5int_set_prompt_types(context, 0);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ret = PKCS12_parse(p12, rdat.data, &y, &x, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ret == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to parse PKCS12 file '%s' with password"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan idopts->cert_filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Seconde PKCS12_parse with password failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[0] = malloc(sizeof(struct _pkinit_cred_info));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->creds[0] == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[0]->cert = x;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[0]->cert_id = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[0]->cert_id_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[0]->key = y;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[1] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (p12)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS12_free(p12);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (x != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_free(x);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (y != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_PKEY_free(y);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_load_fs_cert_and_key(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *certname,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *keyname,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int cindex)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *x = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_PKEY *y = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* load the certificate */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = get_cert(certname, &x);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval != 0 || x == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to load user's certificate from %s: %s"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan certname, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to load user's certificate from '%s'\n", certname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = get_key(keyname, &y);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval != 0 || y == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to load user's private key from %s: %s"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan keyname, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to load user's private key from '%s'\n", keyname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[cindex] = malloc(sizeof(struct _pkinit_cred_info));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->creds[cindex] == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[cindex]->cert = x;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[cindex]->cert_id = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[cindex]->cert_id_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[cindex]->key = y;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[cindex+1] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (x != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_free(x);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (y != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_PKEY_free(y);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_get_certs_fs(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_opts *idopts,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal princ)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idopts->cert_filename == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed to get user's cert location\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idopts->key_filename == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed to get user's private key location\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_load_fs_cert_and_key(context, id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan idopts->cert_filename,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan idopts->key_filename, 0);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_get_certs_dir(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_opts *idopts,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal princ)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KRB_ERR_GENERIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DIR *d = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct dirent *dentry = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char certname[1024];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char keyname[1024];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i = 0, len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *dirname, *suf;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idopts == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idopts->cert_filename == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed to get user's certificate directory location\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOENT;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dirname = idopts->cert_filename;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan d = opendir(dirname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (d == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, errno,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to open directory \"%s\": %s"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dirname, error_message(errno));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return errno;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * We'll assume that certs are named XXX.crt and the corresponding
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * key is named XXX.key
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan while ((i < MAX_CREDS_ALLOWED) && (dentry = readdir(d)) != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Ignore subdirectories and anything starting with a dot */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DT_DIR
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dentry->d_type == DT_DIR)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dentry->d_name[0] == '.')
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = strlen(dentry->d_name);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (len < 5)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan suf = dentry->d_name + (len - 4);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (strncmp(suf, ".crt", 4) != 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Checked length */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (strlen(dirname) + strlen(dentry->d_name) + 2 > sizeof(certname)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Path too long -- directory '%s' and file '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, dirname, dentry->d_name);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) snprintf(certname, sizeof(certname), "%s/%s", dirname, dentry->d_name);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) snprintf(keyname, sizeof(keyname), "%s/%s", dirname, dentry->d_name);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = strlen(keyname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan keyname[len - 3] = 'k';
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan keyname[len - 2] = 'e';
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan keyname[len - 1] = 'y';
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_load_fs_cert_and_key(context, id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan certname, keyname, i);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Successfully loaded cert (and key) for %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, dentry->d_name);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (i == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, ENOENT,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("No suitable cert/key pairs found in directory '%s'"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan idopts->cert_filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: No cert/key pairs found in directory '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, idopts->cert_filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOENT;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (d)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) closedir(d);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_get_certs_pkcs11(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_opts *idopts,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal princ)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef PKINIT_USE_MECH_LIST
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_MECHANISM_TYPE_PTR mechp;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_MECHANISM_INFO info;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_OBJECT_CLASS cls;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_OBJECT_HANDLE obj;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_ATTRIBUTE attrs[4];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_ULONG count;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_CERTIFICATE_TYPE certtype;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_BYTE_PTR cert = NULL, cert_id;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const unsigned char *cp;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i, r;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int nattrs;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *x = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Copy stuff from idopts -> id_cryptoctx */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idopts->p11_module_name != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->p11_module_name = strdup(idopts->p11_module_name);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->p11_module_name == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idopts->token_label != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->token_label = strdup(idopts->token_label);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->token_label == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idopts->cert_label != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->cert_label = strdup(idopts->cert_label);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->cert_label == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Convert the ascii cert_id string into a binary blob */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Solaris Kerberos:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * If the cert_id_string is empty then behave in a similar way to how
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * an empty certlabel is treated - i.e. don't fail now but rather continue
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * as though the certid wasn't specified.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idopts->cert_id_string != NULL && strlen(idopts->cert_id_string) != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIGNUM *bn = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_hex2bn(&bn, idopts->cert_id_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (bn == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->cert_id_len = BN_num_bytes(bn);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->cert_id = malloc((size_t) id_cryptoctx->cert_id_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->cert_id == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_free(bn);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_bn2bin(bn, id_cryptoctx->cert_id);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_free(bn);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->slotid = idopts->slotid;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->pkcs11_method = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_open_session(context, id_cryptoctx)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("can't open pkcs11 session\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef PKINIT_USE_MECH_LIST
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * We'd like to use CKM_SHA1_RSA_PKCS for signing if it's available, but
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * many cards seems to be confused about whether they are capable of
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * this or not. The safe thing seems to be to ignore the mechanism list,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * always use CKM_RSA_PKCS and calculate the sha1 digest ourselves.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->mech = CKM_RSA_PKCS;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_GetMechanismList(id_cryptoctx->slotid, NULL,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &count)) != CKR_OK || count <= 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_GetMechanismList: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan mechp = (CK_MECHANISM_TYPE_PTR) malloc(count * sizeof (CK_MECHANISM_TYPE));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (mechp == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_GetMechanismList(id_cryptoctx->slotid,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan mechp, &count)) != CKR_OK)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < count; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_GetMechanismInfo(id_cryptoctx->slotid,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan mechp[i], &info)) != CKR_OK)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_MECHINFO
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("mech %x flags %x\n", (int) mechp[i], (int) info.flags);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((info.flags & (CKF_SIGN|CKF_DECRYPT)) == (CKF_SIGN|CKF_DECRYPT))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug(" this mech is good for sign & decrypt\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (mechp[i] == CKM_RSA_PKCS) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* This seems backwards... */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->mech =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (info.flags & CKF_SIGN) ? CKM_SHA1_RSA_PKCS : CKM_RSA_PKCS;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(mechp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("got %d mechs from card\n", (int) count);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cls = CKO_CERTIFICATE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[0].type = CKA_CLASS;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[0].pValue = &cls;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[0].ulValueLen = sizeof cls;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan certtype = CKC_X_509;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[1].type = CKA_CERTIFICATE_TYPE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[1].pValue = &certtype;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[1].ulValueLen = sizeof certtype;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nattrs = 2;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* If a cert id and/or label were given, use them too */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->cert_id_len > 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].type = CKA_ID;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].pValue = id_cryptoctx->cert_id;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].ulValueLen = id_cryptoctx->cert_id_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nattrs++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->cert_label != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].type = CKA_LABEL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].pValue = id_cryptoctx->cert_label;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].ulValueLen = strlen(id_cryptoctx->cert_label);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nattrs++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_FindObjectsInit: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; ; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (i >= MAX_CREDS_ALLOWED)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Look for x.509 cert */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &obj, 1, &count)) != CKR_OK || count == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[i] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Get cert and id len */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[0].type = CKA_VALUE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[0].pValue = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[0].ulValueLen = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[1].type = CKA_ID;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[1].pValue = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[1].ulValueLen = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_GetAttributeValue(id_cryptoctx->session,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan obj, attrs, 2)) != CKR_OK && r != CKR_BUFFER_TOO_SMALL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_GetAttributeValue: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cert = (CK_BYTE_PTR) malloc((size_t) attrs[0].ulValueLen + 1);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cert_id = (CK_BYTE_PTR) malloc((size_t) attrs[1].ulValueLen + 1);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cert == NULL || cert_id == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Read the cert and id off the card */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[0].type = CKA_VALUE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[0].pValue = cert;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[1].type = CKA_ID;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[1].pValue = cert_id;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_GetAttributeValue(id_cryptoctx->session,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan obj, attrs, 2)) != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_GetAttributeValue: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("cert %d size %d id %d idlen %d\n", i,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int) attrs[0].ulValueLen, (int) cert_id[0],
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int) attrs[1].ulValueLen);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cp = (unsigned char *) cert;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan x = d2i_X509(NULL, &cp, (int) attrs[0].ulValueLen);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (x == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[i] = malloc(sizeof(struct _pkinit_cred_info));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->creds[i] == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[i]->cert = x;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[i]->key = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[i]->cert_id = cert_id;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[i]->cert_id_len = attrs[1].ulValueLen;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(cert);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cert == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("pkcs11 error while searching for certificates: %s"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIGNUM *cid = BN_bin2bn(id_cryptoctx->cert_id,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->cert_id_len, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *cidstr = BN_bn2hex(cid);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *printstr = id_cryptoctx->cert_id_len ? cidstr : "<none>";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to find any suitable certificates "
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "(certlabel: %s, certid: %s)"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->cert_label ? id_cryptoctx->cert_label : "<none>",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cidstr ? printstr : "<unknown>");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cidstr != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan OPENSSL_free(cidstr);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_free(cid);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanfree_cred_info(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_cred_info *cred)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cred != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cred->cert != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_free(cred->cert);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cred->key != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_PKEY_free(cred->key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cred->cert_id != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(cred->cert_id);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(cred);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_free_cert_info(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < MAX_CREDS_ALLOWED; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->creds[i] != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_cred_info(context, id_cryptoctx, id_cryptoctx->creds[i]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[i] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_load_certs(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_opts *idopts,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal princ)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(idopts->idtype) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case IDTYPE_FILE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_get_certs_fs(context, plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_cryptoctx, idopts,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx, princ);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case IDTYPE_DIR:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_get_certs_dir(context, plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_cryptoctx, idopts,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx, princ);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case IDTYPE_PKCS11:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_get_certs_pkcs11(context, plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_cryptoctx, idopts,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx, princ);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case IDTYPE_PKCS12:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_get_certs_pkcs12(context, plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_cryptoctx, idopts,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx, princ);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Get number of certificates available after crypto_load_certs()
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_cert_get_count(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int *cert_count)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int count;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx == NULL || id_cryptoctx->creds[0] == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (count = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan count <= MAX_CREDS_ALLOWED && id_cryptoctx->creds[count] != NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan count++);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *cert_count = count;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Begin iteration over the certs loaded in crypto_load_certs()
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_cert_iteration_begin(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_iter_handle *ih_ret)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_cert_iter_data *id;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx == NULL || ih_ret == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->creds[0] == NULL) /* No cred info available */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOENT;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id = calloc(1, sizeof(*id));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id->magic = ITER_MAGIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id->plgctx = plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id->reqctx = req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id->idctx = id_cryptoctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id->index = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ih_ret = (pkinit_cert_iter_handle) id;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * End iteration over the certs loaded in crypto_load_certs()
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_cert_iteration_end(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_iter_handle ih)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_cert_iter_data *id = (struct _pkinit_cert_iter_data *)ih;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id == NULL || id->magic != ITER_MAGIC)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(ih);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Get next certificate handle
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_cert_iteration_next(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_iter_handle ih,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_handle *ch_ret)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_cert_iter_data *id = (struct _pkinit_cert_iter_data *)ih;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_cert_data *cd;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id == NULL || id->magic != ITER_MAGIC)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ch_ret == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx = id->idctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->creds[id->index] == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return PKINIT_ITER_NO_MORE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd = calloc(1, sizeof(*cd));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cd == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->magic = CERT_MAGIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->plgctx = id->plgctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->reqctx = id->reqctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->idctx = id->idctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->index = id->index;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->cred = id_cryptoctx->creds[id->index++];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ch_ret = (pkinit_cert_handle)cd;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Release cert handle
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_cert_release(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_handle ch)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_cert_data *cd = (struct _pkinit_cert_data *)ch;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cd == NULL || cd->magic != CERT_MAGIC)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(cd);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Get certificate Key Usage and Extended Key Usage
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_retieve_X509_key_usage(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plgcctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context reqcctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *x,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *ret_ku_bits,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *ret_eku_bits)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int eku_bits = 0, ku_bits = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_BIT_STRING *usage = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ret_ku_bits == NULL && ret_eku_bits == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ret_eku_bits)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ret_eku_bits = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: EKUs not requested, not checking\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto check_kus;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Start with Extended Key usage */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i = X509_get_ext_by_NID(x, NID_ext_key_usage, -1);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (i >= 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EXTENDED_KEY_USAGE *eku;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan eku = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (eku) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OBJECT *certoid;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan certoid = sk_ASN1_OBJECT_value(eku, i);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((OBJ_cmp(certoid, plgcctx->id_pkinit_KPClientAuth)) == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan eku_bits |= PKINIT_EKU_PKINIT;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else if ((OBJ_cmp(certoid, OBJ_nid2obj(NID_ms_smartcard_login))) == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan eku_bits |= PKINIT_EKU_MSSCLOGIN;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else if ((OBJ_cmp(certoid, OBJ_nid2obj(NID_client_auth))) == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan eku_bits |= PKINIT_EKU_CLIENTAUTH;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else if ((OBJ_cmp(certoid, OBJ_nid2obj(NID_email_protect))) == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan eku_bits |= PKINIT_EKU_EMAILPROTECTION;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EXTENDED_KEY_USAGE_free(eku);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning eku 0x%08x\n", __FUNCTION__, eku_bits);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ret_eku_bits = eku_bits;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancheck_kus:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Now the Key Usage bits */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ret_ku_bits)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ret_ku_bits = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: KUs not requested, not checking\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Make sure usage exists before checking bits */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (usage) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ku_bits |= PKINIT_KU_DIGITALSIGNATURE;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!ku_reject(x, X509v3_KU_KEY_ENCIPHERMENT))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ku_bits |= PKINIT_KU_KEYENCIPHERMENT;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_BIT_STRING_free(usage);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning ku 0x%08x\n", __FUNCTION__, ku_bits);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ret_ku_bits = ku_bits;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanout:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Return a string format of an X509_NAME in buf where
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * size is an in/out parameter. On input it is the size
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * of the buffer, and on output it is the actual length
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * of the name.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * If buf is NULL, returns the length req'd to hold name
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic char *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark PhalanX509_NAME_oneline_ex(X509_NAME * a,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *buf,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *size,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned long flag)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO *out = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan out = BIO_new(BIO_s_mem ());
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (X509_NAME_print_ex(out, a, 0, flag) > 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (buf != NULL && *size > (int) BIO_number_written(out)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memset(buf, 0, *size);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_read(out, buf, (int) BIO_number_written(out));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *size = BIO_number_written(out);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_free(out);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Get certificate information
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_cert_get_matching_data(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_handle ch,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_matching_data **ret_md)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_matching_data *md;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal *pkinit_sans =NULL, *upn_sans = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_cert_data *cd = (struct _pkinit_cert_data *)ch;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i, j;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char buf[DN_BUF_LEN];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int bufsize = sizeof(buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cd == NULL || cd->magic != CERT_MAGIC)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ret_md == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan md = calloc(1, sizeof(*md));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (md == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan md->ch = ch;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* get the subject name (in rfc2253 format) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline_ex(X509_get_subject_name(cd->cred->cert),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan buf, &bufsize, XN_FLAG_SEP_COMMA_PLUS);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan md->subject_dn = strdup(buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (md->subject_dn == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* get the issuer name (in rfc2253 format) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline_ex(X509_get_issuer_name(cd->cred->cert),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan buf, &bufsize, XN_FLAG_SEP_COMMA_PLUS);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan md->issuer_dn = strdup(buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (md->issuer_dn == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* get the san data */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = crypto_retrieve_X509_sans(context, cd->plgctx, cd->reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->cred->cert, &pkinit_sans,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &upn_sans, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan j = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_sans != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; pkinit_sans[i] != NULL; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan j++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (upn_sans != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; upn_sans[i] != NULL; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan j++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (j != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan md->sans = calloc((size_t)j+1, sizeof(*md->sans));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (md->sans == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan j = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_sans != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; pkinit_sans[i] != NULL; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan md->sans[j++] = pkinit_sans[i];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(pkinit_sans);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (upn_sans != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; upn_sans[i] != NULL; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan md->sans[j++] = upn_sans[i];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(upn_sans);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan md->sans[j] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan md->sans = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* get the KU and EKU data */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = crypto_retieve_X509_key_usage(context, cd->plgctx, cd->reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->cred->cert,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &md->ku_bits, &md->eku_bits);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ret_md = md;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (md)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan crypto_cert_free_matching_data(context, md);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Free certificate information
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_cert_free_matching_data(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_matching_data *md)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal p;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (md == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (md->subject_dn)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(md->subject_dn);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (md->issuer_dn)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(md->issuer_dn);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (md->sans) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0, p = md->sans[i]; p != NULL; p = md->sans[++i])
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_principal(context, p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(md->sans);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(md);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Make this matching certificate "the chosen one"
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_cert_select(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_cert_matching_data *md)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_cert_data *cd;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (md == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd = (struct _pkinit_cert_data *)md->ch;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cd == NULL || cd->magic != CERT_MAGIC)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* copy the selected cert into our id_cryptoctx */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cd->idctx->my_certs != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_pop_free(cd->idctx->my_certs, X509_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->idctx->my_certs = sk_X509_new_null();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_push(cd->idctx->my_certs, cd->cred->cert);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->idctx->creds[cd->index]->cert = NULL; /* Don't free it twice */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->idctx->cert_index = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cd->idctx->pkcs11_method != 1) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->idctx->my_key = cd->cred->key;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->idctx->creds[cd->index]->key = NULL; /* Don't free it twice */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->idctx->cert_id = cd->cred->cert_id;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->idctx->creds[cd->index]->cert_id = NULL; /* Don't free it twice */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->idctx->cert_id_len = cd->cred->cert_id_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Choose the default certificate as "the chosen one"
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_cert_select_default(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int cert_count = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = crypto_cert_get_count(context, plg_cryptoctx, req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx, &cert_count);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: crypto_cert_get_count error %d, %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, retval, error_message(retval));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cert_count != 1) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to select default certificate: "
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "found %d certs to choose from but there must be exactly one"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cert_count);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: ERROR: There are %d certs to choose from, "
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "but there must be exactly one.\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, cert_count);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto errout;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* copy the selected cert into our id_cryptoctx */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->my_certs != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_pop_free(id_cryptoctx->my_certs, X509_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->my_certs = sk_X509_new_null();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_push(id_cryptoctx->my_certs, id_cryptoctx->creds[0]->cert);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[0]->cert = NULL; /* Don't free it twice */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->cert_index = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->pkcs11_method != 1) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->my_key = id_cryptoctx->creds[0]->key;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[0]->key = NULL; /* Don't free it twice */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifndef WITHOUT_PKCS11
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->cert_id = id_cryptoctx->creds[0]->cert_id;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[0]->cert_id = NULL; /* Don't free it twice */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->cert_id_len = id_cryptoctx->creds[0]->cert_id_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanerrout:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanload_cas_and_crls(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int catype,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *filename)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(X509_INFO) *sk = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(X509) *ca_certs = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(X509_CRL) *ca_crls = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO *in = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KRB_ERR_GENERIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* If there isn't already a stack in the context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * create a temporary one now */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(catype) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CATYPE_ANCHORS:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->trustedCAs != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ca_certs = id_cryptoctx->trustedCAs;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ca_certs = sk_X509_new_null();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ca_certs == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CATYPE_INTERMEDIATES:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->intermediateCAs != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ca_certs = id_cryptoctx->intermediateCAs;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ca_certs = sk_X509_new_null();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ca_certs == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CATYPE_CRLS:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->revoked != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ca_crls = id_cryptoctx->revoked;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ca_crls = sk_X509_CRL_new_null();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ca_crls == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOTSUP;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!(in = BIO_new_file(filename, "r"))) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = errno;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: error opening file '%s': %s\n", __FUNCTION__,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan filename, error_message(errno));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* This loads from a file, a stack of x509/crl/pkey sets */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL)) == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: error reading file '%s'\n", __FUNCTION__, filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EIO;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* scan over the stack created from loading the file contents,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * weed out duplicates, and push new ones onto the return stack
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < sk_X509_INFO_num(sk); i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_INFO *xi = sk_X509_INFO_value(sk, i);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (xi != NULL && xi->x509 != NULL && catype != CATYPE_CRLS) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int j = 0, size = sk_X509_num(ca_certs), flag = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!size) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_push(ca_certs, xi->x509);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan xi->x509 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (j = 0; j < size; j++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *x = sk_X509_value(ca_certs, j);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan flag = X509_cmp(x, xi->x509);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (flag == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (flag != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_push(ca_certs, X509_dup(xi->x509));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (xi != NULL && xi->crl != NULL && catype == CATYPE_CRLS) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int j = 0, size = sk_X509_CRL_num(ca_crls), flag = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!size) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_CRL_push(ca_crls, xi->crl);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan xi->crl = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (j = 0; j < size; j++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_CRL *x = sk_X509_CRL_value(ca_crls, j);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan flag = X509_CRL_cmp(x, xi->crl);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (flag == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (flag != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_push(ca_crls, X509_CRL_dup(xi->crl));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* If we added something and there wasn't a stack in the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * context before, add the temporary stack to the context.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch(catype) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CATYPE_ANCHORS:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (sk_X509_num(ca_certs) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("no anchors in file, %s\n", filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->trustedCAs == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_free(ca_certs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->trustedCAs == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->trustedCAs = ca_certs;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CATYPE_INTERMEDIATES:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (sk_X509_num(ca_certs) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("no intermediates in file, %s\n", filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->intermediateCAs == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_free(ca_certs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->intermediateCAs == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->intermediateCAs = ca_certs;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case CATYPE_CRLS:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (sk_X509_num(ca_crls) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("no crls in file, %s\n", filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->revoked == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_CRL_free(ca_crls);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->revoked == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->revoked = ca_crls;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Should have been caught above! */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: removed "break" as it's never reached */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (in != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_free(in);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (sk != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_INFO_pop_free(sk, X509_INFO_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanload_cas_and_crls_dir(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int catype,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *dirname)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DIR *d = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct dirent *dentry = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char filename[1024];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dirname == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return EINVAL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan d = opendir(dirname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (d == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOENT;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan while ((dentry = readdir(d))) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (strlen(dirname) + strlen(dentry->d_name) + 2 > sizeof(filename)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Path too long -- directory '%s' and file '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, dirname, dentry->d_name);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Ignore subdirectories and anything starting with a dot */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DT_DIR
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dentry->d_type == DT_DIR)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dentry->d_name[0] == '.')
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) snprintf(filename, sizeof(filename), "%s/%s", dirname, dentry->d_name);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = load_cas_and_crls(context, plg_cryptoctx, req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx, catype, filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (d != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) closedir(d);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_load_cas_and_crls(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_opts *idopts,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int idtype,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int catype,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *id)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: called with idtype %s and catype %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, idtype2string(idtype), catype2string(catype));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Removed "break"'s as they are never reached */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch (idtype) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case IDTYPE_FILE:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return load_cas_and_crls(context, plg_cryptoctx, req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx, catype, id);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case IDTYPE_DIR:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return load_cas_and_crls_dir(context, plg_cryptoctx, req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx, catype, id);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOTSUP;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancreate_identifiers_from_stack(STACK_OF(X509) *sk,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_external_principal_identifier *** ids)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i = 0, sk_size = sk_X509_num(sk);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_external_principal_identifier **krb5_cas = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *x = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME *xn = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_ISSUER_AND_SERIAL *is = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char buf[DN_BUF_LEN];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ids = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan malloc((sk_size + 1) * sizeof(krb5_external_principal_identifier *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_cas == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[sk_size] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < sk_size; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i] = (krb5_external_principal_identifier *)malloc(sizeof(krb5_external_principal_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan x = sk_X509_value(sk, i);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("#%d cert= %s\n", i, buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* fill-in subjectName */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->subjectName.magic = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->subjectName.length = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->subjectName.data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan xn = X509_get_subject_name(x);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = i2d_X509_NAME(xn, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p = krb5_cas[i]->subjectName.data = (unsigned char *)malloc((size_t) len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_X509_NAME(xn, &p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->subjectName.length = len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* fill-in issuerAndSerialNumber */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->issuerAndSerialNumber.length = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->issuerAndSerialNumber.magic = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->issuerAndSerialNumber.data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef LONGHORN_BETA_COMPAT
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanif (longhorn == 0) { /* XXX Longhorn doesn't like this */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan is = PKCS7_ISSUER_AND_SERIAL_new();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_INTEGER_free(is->serial);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p = krb5_cas[i]->issuerAndSerialNumber.data =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned char *)malloc((size_t) len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->issuerAndSerialNumber.length = len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef LONGHORN_BETA_COMPAT
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* fill-in subjectKeyIdentifier */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->subjectKeyIdentifier.length = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->subjectKeyIdentifier.magic = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->subjectKeyIdentifier.data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef LONGHORN_BETA_COMPAT
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanif (longhorn == 0) { /* XXX Longhorn doesn't like this */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (X509_get_ext_by_NID(x, NID_subject_key_identifier, -1) >= 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OCTET_STRING *ikeyid = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((ikeyid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL))) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = i2d_ASN1_OCTET_STRING(ikeyid, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p = krb5_cas[i]->subjectKeyIdentifier.data =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned char *)malloc((size_t) len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_ASN1_OCTET_STRING(ikeyid, &p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->subjectKeyIdentifier.length = len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ikeyid != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OCTET_STRING_free(ikeyid);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef LONGHORN_BETA_COMPAT
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (is != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (is->issuer != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_free(is->issuer);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (is->serial != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER_free(is->serial);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(is);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ids = krb5_cas;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_external_principal_identifier(&krb5_cas);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancreate_krb5_invalidCertificates(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_external_principal_identifier *** ids)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(X509) *sk = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ids = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (req_cryptoctx->received_cert == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk = sk_X509_new_null();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (sk == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_push(sk, req_cryptoctx->received_cert);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = create_identifiers_from_stack(sk, ids);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_free(sk);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancreate_krb5_supportedCMSTypes(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_algorithm_identifier ***oids)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_algorithm_identifier **loids = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_octet_data des3oid = {0, 8, (unsigned char *)"\x2A\x86\x48\x86\xF7\x0D\x03\x07" };
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *oids = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan loids = malloc(2 * sizeof(krb5_algorithm_identifier *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (loids == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan loids[1] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan loids[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (loids[0] == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(loids);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_copy_krb5_octet_data(&loids[0]->algorithm, &des3oid);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(loids[0]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(loids);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan loids[0]->parameters.length = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan loids[0]->parameters.data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *oids = loids;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancreate_krb5_trustedCertifiers(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_external_principal_identifier *** ids)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(X509) *sk = id_cryptoctx->trustedCAs;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ids = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->trustedCAs == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return create_identifiers_from_stack(sk, ids);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancreate_krb5_trustedCas(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int flag,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_trusted_ca *** ids)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(X509) *sk = id_cryptoctx->trustedCAs;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i = 0, len = 0, sk_size = sk_X509_num(sk);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_trusted_ca **krb5_cas = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *x = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char buf[DN_BUF_LEN];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME *xn = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_ISSUER_AND_SERIAL *is = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ids = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->trustedCAs == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas = malloc((sk_size + 1) * sizeof(krb5_trusted_ca *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_cas == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[sk_size] = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < sk_size; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i] = (krb5_trusted_ca *)malloc(sizeof(krb5_trusted_ca));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_cas[i] == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan x = sk_X509_value(sk, i);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("#%d cert= %s\n", i, buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch (flag) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case choice_trusted_cas_principalName:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->choice = choice_trusted_cas_principalName;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case choice_trusted_cas_caName:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->choice = choice_trusted_cas_caName;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->u.caName.data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->u.caName.length = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan xn = X509_get_subject_name(x);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = i2d_X509_NAME(xn, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p = krb5_cas[i]->u.caName.data =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned char *)malloc((size_t) len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_X509_NAME(xn, &p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->u.caName.length = len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case choice_trusted_cas_issuerAndSerial:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->choice = choice_trusted_cas_issuerAndSerial;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->u.issuerAndSerial.data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->u.issuerAndSerial.length = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan is = PKCS7_ISSUER_AND_SERIAL_new();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_INTEGER_free(is->serial);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p = krb5_cas[i]->u.issuerAndSerial.data =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned char *)malloc((size_t) len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->u.issuerAndSerial.length = len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (is != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (is->issuer != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_free(is->issuer);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (is->serial != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER_free(is->serial);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(is);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default: break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ids = krb5_cas;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_trusted_ca(&krb5_cas);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancreate_issuerAndSerial(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **out,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *out_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_ISSUER_AND_SERIAL *is = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *cert = req_cryptoctx->received_cert;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (req_cryptoctx->received_cert == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan is = PKCS7_ISSUER_AND_SERIAL_new();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_set(&is->issuer, X509_get_issuer_name(cert));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_INTEGER_free(is->serial);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p = *out = (unsigned char *)malloc((size_t) len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_len = len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_free(is->issuer);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER_free(is->serial);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(is);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkcs7_decrypt(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7 *p7,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO *data)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO *tmpmem = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char buf[4096];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if(p7 == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if(!PKCS7_type_is_enveloped(p7)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("wrong pkcs7 content type\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if(!(tmpmem = pkcs7_dataDecode(context, id_cryptoctx, p7))) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("unable to decrypt pkcs7 object\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Solaris Kerberos: Suppress sun studio compiler warning */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#pragma error_messages (off, E_END_OF_LOOP_CODE_NOT_REACHED)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for(;;) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i = BIO_read(tmpmem, buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (i <= 0) break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_write(data, buf, i);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_free_all(tmpmem);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#pragma error_messages (default, E_END_OF_LOOP_CODE_NOT_REACHED)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_process_td_trusted_certifiers(
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_plg_crypto_context plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_req_crypto_context req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_external_principal_identifier **krb5_trusted_certifiers,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int td_type)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(X509_NAME) *sk_xn = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME *xn = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_ISSUER_AND_SERIAL *is = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OCTET_STRING *id = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char buf[DN_BUF_LEN];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (td_type == TD_TRUSTED_CERTIFIERS)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("received trusted certifiers\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("received invalid certificate\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_xn = sk_X509_NAME_new_null();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan while(krb5_trusted_certifiers[i] != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_trusted_certifiers[i]->subjectName.data != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p = krb5_trusted_certifiers[i]->subjectName.data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan xn = d2i_X509_NAME(NULL, &p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int)krb5_trusted_certifiers[i]->subjectName.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (xn == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(xn, buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (td_type == TD_TRUSTED_CERTIFIERS)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("#%d cert = %s is trusted by kdc\n", i, buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("#%d cert = %s is invalid\n", i, buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_NAME_push(sk_xn, xn);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_trusted_certifiers[i]->issuerAndSerialNumber.data != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p = krb5_trusted_certifiers[i]->issuerAndSerialNumber.data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan is = d2i_PKCS7_ISSUER_AND_SERIAL(NULL, &p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int)krb5_trusted_certifiers[i]->issuerAndSerialNumber.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (is == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(is->issuer, buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (td_type == TD_TRUSTED_CERTIFIERS)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("#%d issuer = %s serial = %ld is trusted bu kdc\n", i,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan buf, ASN1_INTEGER_get(is->serial));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("#%d issuer = %s serial = %ld is invalid\n", i, buf,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER_get(is->serial));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_ISSUER_AND_SERIAL_free(is);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_trusted_certifiers[i]->subjectKeyIdentifier.data != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p = krb5_trusted_certifiers[i]->subjectKeyIdentifier.data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id = d2i_ASN1_OCTET_STRING(NULL, &p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int)krb5_trusted_certifiers[i]->subjectKeyIdentifier.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* XXX */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OCTET_STRING_free(id);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i++;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* XXX Since we not doing anything with received trusted certifiers
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * return an error. this is the place where we can pick a different
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * client certificate based on the information in td_trusted_certifiers
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (sk_xn != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_NAME_pop_free(sk_xn, X509_NAME_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic BIO *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkcs7_dataDecode(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7 *p7)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int jj = 0, tmp_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO *out=NULL,*etmp=NULL,*bio=NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *tmp=NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OCTET_STRING *data_body=NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const EVP_CIPHER *evp_cipher=NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan EVP_CIPHER_CTX *evp_ctx=NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_ALGOR *enc_alg=NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Solaris Kerberos: Not used */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#if 0
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_ALGOR *xalg=NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_RECIP_INFO *ri=NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *cert = sk_X509_value(id_cryptoctx->my_certs,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->cert_index);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7->state=PKCS7_S_HEADER;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rsk=p7->d.enveloped->recipientinfo;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan enc_alg=p7->d.enveloped->enc_data->algorithm;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan data_body=p7->d.enveloped->enc_data->enc_data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (evp_cipher == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Solaris Kerberos: Not used */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#if 0
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan xalg=p7->d.enveloped->enc_data->algorithm;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((etmp=BIO_new(BIO_f_cipher())) == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* It was encrypted, we need to decrypt the secret key
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * with the private key */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Find the recipientInfo which matches the passed certificate
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * (if any)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cert) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int tmp_ret = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tmp_ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cert->cert_info->issuer);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!tmp_ret) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tmp_ret = M_ASN1_INTEGER_cmp(cert->cert_info->serialNumber,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ri->issuer_and_serial->serial);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!tmp_ret)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ri=NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ri == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7err(PKCS7_F_PKCS7_DATADECODE,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* If we haven't got a certificate try each ri in turn */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cert == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan jj = pkinit_decode_data(context, id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_STRING_data(ri->enc_key),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned int) M_ASN1_STRING_length(ri->enc_key),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &tmp, &tmp_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (jj) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!jj && tmp_len > 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan jj = tmp_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ERR_clear_error();
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ri = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ri == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_KEY);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan jj = pkinit_decode_data(context, id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_STRING_data(ri->enc_key),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned int) M_ASN1_STRING_length(ri->enc_key),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &tmp, &tmp_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: tmp_len is unsigned. Cannot be < 0 */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (jj || tmp_len == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan jj = tmp_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan evp_ctx=NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_get_cipher_ctx(etmp,&evp_ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Some S/MIME clients don't use the same key
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * and effective key length. The key length is
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * determined by the size of the decrypted RSA key.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, (int)jj)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7err(PKCS7_F_PKCS7_DATADECODE,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan OPENSSL_cleanse(tmp,jj);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (out == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan out=etmp;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_push(out,etmp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan etmp=NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (data_body->length > 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan bio = BIO_new_mem_buf(data_body->data, data_body->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan bio=BIO_new(BIO_s_mem());
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_set_mem_eof_return(bio,0);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_push(out,bio);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan bio=NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (out != NULL) BIO_free_all(out);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (etmp != NULL) BIO_free_all(etmp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (bio != NULL) BIO_free_all(bio);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan out=NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanout:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (tmp != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(tmp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return(out);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalander_decode_data(unsigned char *data, long data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **out, long *out_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KRB_ERR_GENERIC;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OCTET_STRING *s = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const unsigned char *p = data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((s = d2i_ASN1_BIT_STRING(NULL, &p, data_len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_len = s->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*out = (unsigned char *) malloc((size_t) *out_len + 1)) == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = ENOMEM;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(*out, s->data, (size_t) s->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*out)[s->length] = '\0';
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (s != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OCTET_STRING_free(s);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return retval;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef DEBUG_DH
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanprint_dh(DH * dh, char *msg)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO *bio_err = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan bio_err = BIO_new(BIO_s_file());
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (msg)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_puts(bio_err, (const char *)msg);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (dh)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DHparams_print(bio_err, dh);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_print(bio_err, dh->q);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_puts(bio_err, (const char *)"\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_free(bio_err);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanprint_pubkey(BIGNUM * key, char *msg)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO *bio_err = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan bio_err = BIO_new(BIO_s_file());
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (msg)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_puts(bio_err, (const char *)msg);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (key)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_print(bio_err, key);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_puts(bio_err, "\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_free(bio_err);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Solaris Kerberos:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Error message generation has changed so gettext() can be used
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#if 0
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic char *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_pkcs11_code_to_text(int err)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan static char uc[64];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; pkcs11_errstrings[i].text != NULL; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkcs11_errstrings[i].code == err)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkcs11_errstrings[i].text != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (pkcs11_errstrings[i].text);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan snprintf(uc, 64, gettext("unknown code 0x%x"), err);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (uc);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic char *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_pkcs11_code_to_text(int err) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return pkcs11_error_table(err);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}