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.
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle * Copyright (c) 2012, OmniTI Computer Consulting, Inc. 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>
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash#include <assert.h>
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash#include <security/pam_appl.h>
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash#include <ctype.h>
31a2903539e29171f5c5da80e5c9616c70108116Mark Phalan#include "k5-int.h"
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash#include <ctype.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;
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash ctx->PIN = 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;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash (void) memset(ctx->creds, 0, sizeof(ctx->creds));
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) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (ctx->session != CK_INVALID_HANDLE) {
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);
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash if (ctx->PIN != NULL) {
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash (void) memset(ctx->PIN, 0, strlen(ctx->PIN));
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash free(ctx->PIN);
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash }
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));
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle size = sk_X509_CRL_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");
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle print_buffer((unsigned char *)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
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash/*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Solaris Kerberos: this is a new function that does not exist yet in the MIT
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * code.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash *
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * labelstr will be C string containing token label with trailing white space
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * removed.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveashstatic void
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveashtrim_token_label(CK_TOKEN_INFO *tinfo, char *labelstr, unsigned int labelstr_len)
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash{
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash int i;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash assert(labelstr_len > sizeof (tinfo->label));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * \0 terminate labelstr in case the last char in the token label is
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * non-whitespace
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash labelstr[sizeof (tinfo->label)] = '\0';
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash (void) memcpy(labelstr, (char *) tinfo->label, sizeof (tinfo->label));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* init i so terminating \0 is skipped */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash for (i = sizeof (tinfo->label) - 1; i >= 0; i--) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (labelstr[i] == ' ')
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash labelstr[i] = '\0';
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash else
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash break;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash}
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash/*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Solaris Kerberos: this is a new function that does not exist yet in the MIT
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * code.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveashstatic krb5_error_code
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveashpkinit_prompt_user(krb5_context context,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_identity_crypto_context cctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_data *reply,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash char *prompt,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash int hidden)
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash{
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_error_code r;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_prompt kprompt;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_prompt_type prompt_type;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (cctx->prompter == NULL)
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (EINVAL);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash kprompt.prompt = prompt;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash kprompt.hidden = hidden;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash kprompt.reply = reply;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Note, assuming this type for now, may need to be passed in in the future.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash prompt_type = KRB5_PROMPT_TYPE_PREAUTH;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* PROMPTER_INVOCATION */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash k5int_set_prompt_types(context, &prompt_type);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = (*cctx->prompter)(context, cctx->prompter_data,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash NULL, NULL, 1, &kprompt);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash k5int_set_prompt_types(context, NULL);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (r);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash}
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash/*
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash * Solaris Kerberos: this function was changed to support a PIN being passed
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash * in. If that is the case the user will not be prompted for their PIN.
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash */
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 int r = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (tip->flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rdat.data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rdat.length = 0;
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash } else if (id_cryptoctx->PIN != NULL) {
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash if ((rdat.data = strdup(id_cryptoctx->PIN)) == NULL)
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash return (ENOMEM);
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash /*
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash * Don't include NULL string terminator in length calculation as this
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash * PIN is passed to the C_Login function and only the text chars should
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash * be considered to be the PIN.
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash */
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash rdat.length = strlen(id_cryptoctx->PIN);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* Solaris Kerberos - trim token label */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash char tmplabel[sizeof (tip->label) + 1];
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,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will 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 */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash trim_token_label(tip, tmplabel, sizeof (tmplabel));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash (void) snprintf(prompt, prompt_len, gettext("%s PIN"), tmplabel);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
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);
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash rdat.data = malloc(tip->ulMaxPinLen + 2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rdat.length = tip->ulMaxPinLen + 1;
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash /*
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash * Note that the prompter function will set rdat.length such that the
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash * NULL terminator is not included
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* PROMPTER_INVOCATION */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = pkinit_prompt_user(context, id_cryptoctx, &rdat, prompt, 1);
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,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash 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 }
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash if (rdat.data) {
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash (void) memset(rdat.data, 0, rdat.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free(rdat.data);
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (r);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash/*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Solaris Kerberos: added these structs in support of prompting user for
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * missing token.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveashstruct _token_entry {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CK_SLOT_ID slotID;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CK_SESSION_HANDLE session;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CK_TOKEN_INFO token_info;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash};
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveashstruct _token_choices {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash unsigned int numtokens;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash struct _token_entry *token_array;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash};
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash/*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Solaris Kerberos: this is a new function that does not exist yet in the MIT
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * code.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic krb5_error_code
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveashpkinit_prompt_token(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_identity_crypto_context cctx)
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash{
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash char tmpbuf[4];
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_data reply;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash char *token_prompt = gettext("If you have a smartcard insert it now. "
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash "Press enter to continue");
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash reply.data = tmpbuf;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash reply.length = sizeof(tmpbuf);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* note, don't care about the reply */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (pkinit_prompt_user(context, cctx, &reply, token_prompt, 0));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash}
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash/*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Solaris Kerberos: new defines for prompting support.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash#define CHOOSE_THIS_TOKEN 0
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash#define CHOOSE_RESCAN 1
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash#define CHOOSE_SKIP 2
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash#define CHOOSE_SEE_NEXT 3
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash#define RESCAN_TOKENS -1
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash#define SKIP_TOKENS -2
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash/*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Solaris Kerberos: this is a new function that does not exist yet in the MIT
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * code.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash *
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * This prompts to user for various choices regarding a token to use. Note
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * that if there is no error, choice will be set to one of:
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * - the token_choices->token_array entry
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * - RESCAN_TOKENS
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * - SKIP_TOKENS
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveashstatic int
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveashpkinit_choose_tokens(krb5_context context,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_identity_crypto_context cctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash struct _token_choices *token_choices,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash int *choice)
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash{
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_error_code r;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Assuming that PAM_MAX_MSG_SIZE is a reasonable restriction. Note that -
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * 2 is to account for the fact that a krb prompter to PAM conv bridge will
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * add ": ".
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash char prompt[PAM_MAX_MSG_SIZE - 2];
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash char tmpbuf[4];
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash char tmplabel[sizeof (token_choices->token_array->token_info.label) + 1];
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_data reply;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash int i, num_used, tmpchoice;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash assert(token_choices != NULL);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash assert(choice != NULL);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* Create the menu prompt */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* only need to do this once before the for loop */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash reply.data = tmpbuf;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash for (i = 0; i < token_choices->numtokens; i++) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash trim_token_label(&token_choices->token_array[i].token_info, tmplabel,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash sizeof (tmplabel));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (i == (token_choices->numtokens - 1)) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* no more smartcards/tokens */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((num_used = snprintf(prompt, sizeof (prompt),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash "%s\n%d: %s \"%s\" %s %d\n%d: %s\n%d: %s\n",
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * TRANSLATION_NOTE: Translations of the
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * following 5 strings must not exceed 450
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * bytes total.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Select one of the following and press enter:"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CHOOSE_THIS_TOKEN, gettext("Use smartcard"), tmplabel,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("in slot"), token_choices->token_array[i].slotID,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CHOOSE_RESCAN, gettext("Rescan for newly inserted smartcard"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CHOOSE_SKIP, gettext("Skip smartcard authentication")))
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash >= sizeof (prompt)) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("pkinit_choose_tokens: buffer overflow num_used: %d,"
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash " sizeof prompt: %d\n", num_used, sizeof (prompt));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, EINVAL,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("In pkinit_choose_tokens: prompt size"
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash " %d exceeds prompt buffer size %d"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash num_used, sizeof(prompt));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash (void) snprintf(prompt, sizeof (prompt), "%s",
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Error: PKINIT prompt message is too large for buffer, "
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash "please alert the system administrator. Press enter to "
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash "continue"));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash reply.length = sizeof(tmpbuf);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r = pkinit_prompt_user(context, cctx, &reply, prompt, 0)) != 0 )
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (r);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (EINVAL);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((num_used = snprintf(prompt, sizeof (prompt),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash "%s\n%d: %s \"%s\" %s %d\n%d: %s\n%d: %s\n%d: %s\n",
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * TRANSLATION_NOTE: Translations of the
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * following 6 strings must not exceed 445
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * bytes total.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Select one of the following and press enter:"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CHOOSE_THIS_TOKEN, gettext("Use smartcard"), tmplabel,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("in slot"), token_choices->token_array[i].slotID,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CHOOSE_RESCAN, gettext("Rescan for newly inserted smartcard"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CHOOSE_SKIP, gettext("Skip smartcard authentication"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CHOOSE_SEE_NEXT, gettext("See next smartcard")))
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash >= sizeof (prompt)) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("pkinit_choose_tokens: buffer overflow num_used: %d,"
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash " sizeof prompt: %d\n", num_used, sizeof (prompt));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, EINVAL,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("In pkinit_choose_tokens: prompt size"
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash " %d exceeds prompt buffer size %d"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash num_used, sizeof(prompt));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash (void) snprintf(prompt, sizeof (prompt), "%s",
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Error: PKINIT prompt message is too large for buffer, "
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash "please alert the system administrator. Press enter to "
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash "continue"));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash reply.length = sizeof(tmpbuf);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r = pkinit_prompt_user(context, cctx, &reply, prompt, 0)) != 0 )
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (r);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (EINVAL);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * reply.length needs to be reset to length of tmpbuf before calling
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * prompter
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash reply.length = sizeof(tmpbuf);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r = pkinit_prompt_user(context, cctx, &reply, prompt, 0)) != 0 )
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (r);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (reply.length == 0) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (EINVAL);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash char *cp = reply.data;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* reply better be digits */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash while (*cp != NULL) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (!isdigit(*cp++))
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (EINVAL);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash errno = 0;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash tmpchoice = (int) strtol(reply.data, (char **)NULL, 10);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (errno != 0)
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (errno);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash switch (tmpchoice) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash case CHOOSE_THIS_TOKEN:
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash *choice = i; /* chosen entry of token_choices->token_array */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (0);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash case CHOOSE_RESCAN:
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash *choice = RESCAN_TOKENS; /* rescan for new smartcard */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (0);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash case CHOOSE_SKIP:
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash *choice = SKIP_TOKENS; /* skip smartcard auth */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (0);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash case CHOOSE_SEE_NEXT: /* see next smartcard */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash continue;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash default:
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (EINVAL);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (0);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash}
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash/*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Solaris Kerberos: this is a new function that does not exist yet in the MIT
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * code.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash *
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Note, this isn't the best solution to providing a function to check the
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * certs in a token however I wanted to avoid rewriting a bunch of code so I
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * settled for some duplication of processing.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveashstatic krb5_error_code
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveashcheck_load_certs(krb5_context context,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CK_SESSION_HANDLE session,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_plg_crypto_context plg_cryptoctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_req_crypto_context req_cryptoctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_identity_crypto_context id_cryptoctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_principal princ,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash int do_matching,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash int load_cert)
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash{
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CK_OBJECT_CLASS cls;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CK_OBJECT_HANDLE obj;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CK_ATTRIBUTE attrs[4];
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CK_ULONG count;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CK_CERTIFICATE_TYPE certtype;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CK_BYTE_PTR cert = NULL, cert_id = NULL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash const unsigned char *cp;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash int i, r;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash unsigned int nattrs;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash X509 *x = NULL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cls = CKO_CERTIFICATE;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[0].type = CKA_CLASS;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[0].pValue = &cls;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[0].ulValueLen = sizeof cls;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash certtype = CKC_X_509;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[1].type = CKA_CERTIFICATE_TYPE;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[1].pValue = &certtype;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[1].ulValueLen = sizeof certtype;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash nattrs = 2;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* If a cert id and/or label were given, use them too */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (id_cryptoctx->cert_id_len > 0) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[nattrs].type = CKA_ID;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[nattrs].pValue = id_cryptoctx->cert_id;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[nattrs].ulValueLen = id_cryptoctx->cert_id_len;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash nattrs++;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (id_cryptoctx->cert_label != NULL) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[nattrs].type = CKA_LABEL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[nattrs].pValue = id_cryptoctx->cert_label;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[nattrs].ulValueLen = strlen(id_cryptoctx->cert_label);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash nattrs++;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = id_cryptoctx->p11->C_FindObjectsInit(session, attrs, nattrs);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (r != CKR_OK) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("C_FindObjectsInit: %s\n", pkinit_pkcs11_code_to_text(r));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, EINVAL,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("PKCS11 error from C_FindObjectsInit: %s"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_pkcs11_code_to_text(r));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = EINVAL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash for (i = 0; ; i++) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (i >= MAX_CREDS_ALLOWED) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = EINVAL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* Look for x.509 cert */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* Solaris Kerberos */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r = id_cryptoctx->p11->C_FindObjects(session, &obj, 1, &count))
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash != CKR_OK || count == 0) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash id_cryptoctx->creds[i] = NULL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash break;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* Get cert and id len */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[0].type = CKA_VALUE;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[0].pValue = NULL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[0].ulValueLen = 0;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[1].type = CKA_ID;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[1].pValue = NULL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[1].ulValueLen = 0;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r = id_cryptoctx->p11->C_GetAttributeValue(session,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash obj,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash 2)) != CKR_OK &&
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r != CKR_BUFFER_TOO_SMALL) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("C_GetAttributeValue: %s\n", pkinit_pkcs11_code_to_text(r));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, EINVAL,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Error from PKCS11 C_GetAttributeValue: %s"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_pkcs11_code_to_text(r));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = EINVAL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cert = malloc((size_t) attrs[0].ulValueLen + 1);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (cert == NULL) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = ENOMEM;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cert_id = malloc((size_t) attrs[1].ulValueLen + 1);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (cert_id == NULL) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = ENOMEM;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* Read the cert and id off the card */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[0].type = CKA_VALUE;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[0].pValue = cert;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[1].type = CKA_ID;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash attrs[1].pValue = cert_id;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r = id_cryptoctx->p11->C_GetAttributeValue(session,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash obj, attrs, 2)) != CKR_OK) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("C_GetAttributeValue: %s\n", pkinit_pkcs11_code_to_text(r));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, EINVAL,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Error from PKCS11 C_GetAttributeValue: %s"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_pkcs11_code_to_text(r));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = EINVAL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("cert %d size %d id %d idlen %d\n", i,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash (int) attrs[0].ulValueLen, (int) cert_id[0],
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash (int) attrs[1].ulValueLen);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cp = (unsigned char *) cert;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash x = d2i_X509(NULL, &cp, (int) attrs[0].ulValueLen);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (x == NULL) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = EINVAL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash id_cryptoctx->creds[i] = malloc(sizeof(struct _pkinit_cred_info));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (id_cryptoctx->creds[i] == NULL) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = ENOMEM;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash id_cryptoctx->creds[i]->cert = x;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash id_cryptoctx->creds[i]->key = NULL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash id_cryptoctx->creds[i]->cert_id = cert_id;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cert_id = NULL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash id_cryptoctx->creds[i]->cert_id_len = attrs[1].ulValueLen;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash free(cert);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cert = NULL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash id_cryptoctx->p11->C_FindObjectsFinal(session);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (id_cryptoctx->creds[0] == NULL || id_cryptoctx->creds[0]->cert == NULL) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = ENOENT;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else if (do_matching){
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Do not let pkinit_cert_matching set the primary cert in id_cryptoctx
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * as this will be done later.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = pkinit_cert_matching(context, plg_cryptoctx, req_cryptoctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash id_cryptoctx, princ, FALSE);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveashout:
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r != 0 || !load_cert) &&
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash id_cryptoctx->creds[0] != NULL &&
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash id_cryptoctx->creds[0]->cert != NULL) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * If there's an error or load_cert isn't 1 free all the certs loaded
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * onto id_cryptoctx.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash (void) crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash id_cryptoctx);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (cert)
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash free(cert);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (cert_id)
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash free(cert_id);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (r);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash}
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash/*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Solaris Kerberos: this function has been significantly modified to prompt
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * the user in certain cases so defer to this version when resyncing MIT code.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash *
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * pkinit_open_session now does several things including prompting the user if
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * do_matching is set which indicates the code is executing in a client
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * context. This function fills out a pkinit_identity_crypto_context with a
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * set of certs and a open session if a token can be found that matches all
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * supplied criteria. If no token is found then the user is prompted one time
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * to insert their token. If there is more than one token that matches all
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * client criteria the user is prompted to make a choice if in client context.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * If do_matching is false (KDC context) then the first token matching all
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * server criteria is chosen.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveashstatic krb5_error_code
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveashpkinit_open_session(krb5_context context,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_plg_crypto_context plg_cryptoctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_req_crypto_context req_cryptoctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_identity_crypto_context cctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_principal princ,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash int do_matching)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i, r;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_ULONG count = 0;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CK_SLOT_ID_PTR slotlist = NULL, tmpslotlist = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_TOKEN_INFO tinfo;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_boolean tokenmatch = FALSE;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CK_SESSION_HANDLE tmpsession = NULL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash struct _token_choices token_choices;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash int choice = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (cctx->session != CK_INVALID_HANDLE)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0; /* session already open */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Load module */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (cctx->p11_module == NULL) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->p11_module =
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_C_LoadModule(cctx->p11_module_name, &cctx->p11);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (cctx->p11_module == NULL)
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
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));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Error from PKCS11 C_Initialize: %s"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash (void) memset(&token_choices, 0, sizeof(token_choices));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
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);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * First make sure that is an applicable slot otherwise fail.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash *
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Start by getting a count of all slots with or without tokens.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r = cctx->p11->C_GetSlotList(FALSE, NULL, &count)) != CKR_OK) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("C_GetSlotList: %s\n", pkinit_pkcs11_code_to_text(r));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Error trying to get PKCS11 slot list: %s"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_pkcs11_code_to_text(r));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash if (count == 0) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* There are no slots so bail */
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash krb5_set_error_message(context, r,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("No PKCS11 slots found"));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("pkinit_open_session: no slots, count: %d\n", count);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else if (cctx->slotid != PK_NOSLOT) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* See if any of the slots match the specified slotID */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash tmpslotlist = malloc(count * sizeof (CK_SLOT_ID));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (tmpslotlist == NULL) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, ENOMEM,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Memory allocation error:"));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r = cctx->p11->C_GetSlotList(FALSE, tmpslotlist, &count)) != CKR_OK) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Error trying to get PKCS11 slot list: %s"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_pkcs11_code_to_text(r));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("C_GetSlotList: %s\n", pkinit_pkcs11_code_to_text(r));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash for (i = 0; i < count && cctx->slotid != tmpslotlist[i]; i++)
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash continue;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (i >= count) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* no slots match */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, r,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Requested PKCS11 slot ID %d not found"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->slotid);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("open_session: no matching slot found for slotID %d\n",
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->slotid);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveashtryagain:
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* get count of slots that have tokens */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r = cctx->p11->C_GetSlotList(TRUE, NULL, &count)) != CKR_OK) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("C_GetSlotList: %s\n", pkinit_pkcs11_code_to_text(r));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Error trying to get PKCS11 slot list: %s"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_pkcs11_code_to_text(r));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash goto out;
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash }
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (count == 0) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Note, never prompt if !do_matching as this implies KDC side
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * processing
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (!(cctx->p11flags & C_PROMPTED_USER) && do_matching) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* found slot(s) but no token so prompt and try again */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r = pkinit_prompt_token(context, cctx)) == 0) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->p11flags |= C_PROMPTED_USER;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto tryagain;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("open_session: prompt for token/smart card failed\n");
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, r,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Prompt for token/smart card failed"));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* already prompted once so bailing */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, r,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("No smart card tokens found"));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("pkinit_open_session: no token, already prompted\n");
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (slotlist != NULL)
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash free(slotlist);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash slotlist = malloc(count * sizeof (CK_SLOT_ID));
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash if (slotlist == NULL) {
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash gettext("Memory allocation error"));
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash goto out;
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash }
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash /*
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash * Solaris Kerberos: get list of PKCS11 slotid's that have tokens.
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash */
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash if (cctx->p11->C_GetSlotList(TRUE, slotlist, &count) != CKR_OK) {
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash gettext("Error trying to get PKCS11 slot list: %s"),
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash pkinit_pkcs11_code_to_text(r));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("C_GetSlotList: %s\n", pkinit_pkcs11_code_to_text(r));
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash token_choices.numtokens = 0;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash token_choices.token_array = malloc(count * sizeof (*token_choices.token_array));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (token_choices.token_array == NULL) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, r,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Memory allocation error"));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* examine all the tokens */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < count; i++) {
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash /*
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash * Solaris Kerberos: if a slotid was specified skip slots that don't
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash * match.
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash */
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash if (cctx->slotid != PK_NOSLOT && cctx->slotid != slotlist[i])
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash continue;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Open session */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = cctx->p11->C_OpenSession(slotlist[i], CKF_SERIAL_SESSION,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash NULL, NULL, &tmpsession)) != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_OpenSession: %s\n", pkinit_pkcs11_code_to_text(r));
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Error trying to open PKCS11 session: %s"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_pkcs11_code_to_text(r));
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash goto out;
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));
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Error trying to read PKCS11 token: %s"),
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkinit_pkcs11_code_to_text(r));
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->p11->C_CloseSession(tmpsession);
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash if (cctx->token_label == NULL) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * If the token doesn't require login to examine the certs then
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * let's check the certs out to see if any match the criteria if
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * any.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (!(tinfo.flags & CKF_LOGIN_REQUIRED)) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * It's okay to check the certs if we don't have to login but
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * don't load the certs onto cctx at this point, this will be
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * done later in this function for the chosen token.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r = check_load_certs(context, tmpsession, plg_cryptoctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash req_cryptoctx, cctx, princ,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash do_matching, 0)) == 0) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash tokenmatch = TRUE;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else if (r != ENOENT){
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->p11->C_CloseSession(tmpsession);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* ignore ENOENT here */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = 0;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash tokenmatch = TRUE;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash } else {
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash /* + 1 so tokenlabelstr can be \0 terminated */
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash char tokenlabelstr[sizeof (tinfo.label) + 1];
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Convert token label into C string with trailing white space
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * trimmed.
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash trim_token_label(&tinfo, tokenlabelstr, sizeof (tokenlabelstr));
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash pkiDebug("open_session: slotid %d token found: \"%s\", "
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash "cctx->token_label: \"%s\"\n",
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash slotlist[i], tokenlabelstr, (char *) cctx->token_label);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash if (!strcmp(cctx->token_label, tokenlabelstr)) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (!(tinfo.flags & CKF_LOGIN_REQUIRED)) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * It's okay to check the certs if we don't have to login but
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * don't load the certs onto cctx at this point, this will be
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * done later in this function for the chosen token.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r = check_load_certs(context, tmpsession, plg_cryptoctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash req_cryptoctx, cctx, princ,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash do_matching, 0)) == 0) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash tokenmatch = TRUE;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else if (r != ENOENT){
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->p11->C_CloseSession(tmpsession);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* ignore ENOENT here */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = 0;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash tokenmatch = TRUE;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash }
03e68e16360787df5115ab1eaf2a78ff24c65ef5Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (tokenmatch == TRUE) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* add the token to token_choices.token_array */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash token_choices.token_array[token_choices.numtokens].slotID = slotlist[i];
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash token_choices.token_array[token_choices.numtokens].session = tmpsession;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash token_choices.token_array[token_choices.numtokens].token_info = tinfo;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash token_choices.numtokens++;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* !do_matching implies we take the first matching token */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (!do_matching)
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash break;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash else
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash tokenmatch = FALSE;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->p11->C_CloseSession(tmpsession);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (token_choices.numtokens == 0) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Solaris Kerberos: prompt for token one time if there was no token
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * and do_matching is 1 (see earlier comment about do_matching).
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (!(cctx->p11flags & C_PROMPTED_USER) && do_matching) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r = pkinit_prompt_token(context, cctx)) == 0) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->p11flags |= C_PROMPTED_USER;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto tryagain;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("open_session: prompt for token/smart card failed\n");
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, r,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Prompt for token/smart card failed"));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, r,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("No smart card tokens found"));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("open_session: no matching token found\n");
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else if (token_choices.numtokens == 1) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((token_choices.token_array[0].token_info.flags & CKF_LOGIN_REQUIRED) &&
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash !(cctx->p11flags & C_PROMPTED_USER) &&
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash do_matching) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r = pkinit_choose_tokens(context, cctx, &token_choices, &choice)) != 0) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("pkinit_open_session: pkinit_choose_tokens failed: %d\n", r);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, r,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Prompt for token/smart card failed"));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (choice == RESCAN_TOKENS) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* rescan for new smartcard/token */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash for (i = 0; i < token_choices.numtokens; i++) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* close all sessions */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->p11->C_CloseSession(token_choices.token_array[i].session);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash free(token_choices.token_array);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash token_choices.token_array = NULL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash token_choices.numtokens = 0;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto tryagain;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else if (choice == SKIP_TOKENS) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* do not use smartcard/token for auth */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->p11flags |= (C_PROMPTED_USER|C_SKIP_PKCS11_AUTH);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->p11flags |= C_PROMPTED_USER;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash choice = 0; /* really the only choice is the first token_array entry */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else if (!(cctx->p11flags & C_PROMPTED_USER) && do_matching) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* > 1 token so present menu of token choices, let the user decide. */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((r = pkinit_choose_tokens(context, cctx, &token_choices, &choice)) != 0) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash pkiDebug("pkinit_open_session: pkinit_choose_tokens failed: %d\n", r);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_set_error_message(context, r,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash gettext("Prompt for token/smart card failed"));
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (choice == RESCAN_TOKENS) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* rescan for new smartcard/token */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash for (i = 0; i < token_choices.numtokens; i++) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* close all sessions */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->p11->C_CloseSession(token_choices.token_array[i].session);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash free(token_choices.token_array);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash token_choices.token_array = NULL;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash token_choices.numtokens = 0;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto tryagain;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else if (choice == SKIP_TOKENS) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* do not use smartcard/token for auth */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->p11flags |= (C_PROMPTED_USER|C_SKIP_PKCS11_AUTH);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->p11flags |= C_PROMPTED_USER;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash goto out;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->slotid = token_choices.token_array[choice].slotID;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->session = token_choices.token_array[choice].session;
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash
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 */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if ((token_choices.token_array[choice].token_info.flags & CKF_LOGIN_REQUIRED) &&
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash !(cctx->p11flags & C_LOGIN_DONE)) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = pkinit_login(context, cctx, &token_choices.token_array[choice].token_info);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (r == 0) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* Doing this again to load the certs into cctx. */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash r = check_load_certs(context, cctx->session, plg_cryptoctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash req_cryptoctx, cctx, princ, do_matching, 1);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveashout:
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash if (slotlist != NULL)
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash free(slotlist);
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (tmpslotlist != NULL)
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash free(tmpslotlist);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (token_choices.token_array != NULL) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (r != 0) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* close all sessions if there's an error */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash for (i = 0; i < token_choices.numtokens; i++) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->p11->C_CloseSession(token_choices.token_array[i].session);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->session = CK_INVALID_HANDLE;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash } else {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /* close sessions not chosen */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash for (i = 0; i < token_choices.numtokens; i++) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (i != choice) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash cctx->p11->C_CloseSession(token_choices.token_array[i].session);
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash free(token_choices.token_array);
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash }
e4b3f55340b7a7e15431eae460c7f7a664e20b18Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash 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
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Solaris Kerberos: assume session is open and libpkcs11 funcs have been
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * loaded.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash assert(id_cryptoctx->p11 != NULL);
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
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash /*
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * Solaris Kerberos: assume session is open and libpkcs11 funcs have been
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash * loaded.
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash */
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash assert(id_cryptoctx->p11 != NULL);
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
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle#if OPENSSL_VERSION_NUMBER < 0x10000000L
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = EVP_PKEY_decrypt(buf, data, (int)data_len, pkey);
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle#else
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle len = EVP_PKEY_decrypt_old(buf, data, (int)data_len, pkey);
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle#endif
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,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash 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,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash 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,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash 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,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash 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
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash if (id_cryptoctx->PIN != NULL) {
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash /* Solaris Kerberos: use PIN if set */
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash rdat.data = id_cryptoctx->PIN;
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash /* note rdat.length isn't needed in this case */
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash } else {
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash (void) memset(prompt_reply, '\0', sizeof(prompt_reply));
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash rdat.data = prompt_reply;
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash rdat.length = sizeof(prompt_reply);
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash r = snprintf(prompt_string, sizeof(prompt_string), "%s %s",
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash prompt_prefix, idopts->cert_filename);
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash if (r >= sizeof(prompt_string)) {
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash pkiDebug("Prompt string, '%s %s', is too long!\n",
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash prompt_prefix, idopts->cert_filename);
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash goto cleanup;
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash }
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash kprompt.prompt = prompt_string;
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash kprompt.hidden = 1;
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash kprompt.reply = &rdat;
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash prompt_type = KRB5_PROMPT_TYPE_PREAUTH;
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash /* PROMPTER_INVOCATION */
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash k5int_set_prompt_types(context, &prompt_type);
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash r = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data,
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash NULL, NULL, 1, &kprompt);
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash k5int_set_prompt_types(context, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
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,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash 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,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash 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,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash 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,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash 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,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_principal princ,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash int do_matching)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#ifdef PKINIT_USE_MECH_LIST
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash CK_MECHANISM_TYPE_PTR mechp = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CK_MECHANISM_INFO info;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#endif
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash if (id_cryptoctx->p11flags & C_SKIP_PKCS11_AUTH)
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return KRB5KDC_ERR_PREAUTH_FAILED;
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 }
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash if (idopts->PIN != NULL) {
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash id_cryptoctx->PIN = strdup(idopts->PIN);
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash if (id_cryptoctx->PIN == NULL)
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash return ENOMEM;
488060a6285c53d78d4e5360e7db00d6d544d960Will Fiveash }
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#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,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash mechp, &count)) != CKR_OK) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash free(mechp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < count; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_GetMechanismInfo(id_cryptoctx->slotid,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash mechp[i], &info)) != CKR_OK) {
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash free(mechp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return KRB5KDC_ERR_PREAUTH_FAILED;
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash }
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
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash return (pkinit_open_session(context, plg_cryptoctx, req_cryptoctx,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash id_cryptoctx, princ, do_matching));
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,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash krb5_principal princ,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash int do_matching)
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,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash id_cryptoctx, princ, do_matching);
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,
9e11d51c0ad2b26ad2cd7f23707e4fb3005fd5b4Will Fiveash 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) {
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle sk_X509_CRL_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:
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle if (sk_X509_CRL_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}