PSARC/2013/383 OpenSSL FIPS 140-2 version update s11-update
authorMisaki Miyashita <Misaki.Miyashita@Oracle.COM>
Wed, 29 Jan 2014 11:12:07 -0800
branchs11-update
changeset 2921 8da1e7689d13
parent 2919 c18ab9ed07fe
child 2922 a20504fc0f7b
PSARC/2013/383 OpenSSL FIPS 140-2 version update 15801760 SUNBT7181479 FIPS-capable version of OpenSSL using OpenSSL FIPS Object Module v2 18024740 problem in UTILITY/OPENSSL 17836054 EVP_DigestUpdate crashes because of a NULL pointer 17952352 FIPS OpenSSL needs same patches as non-FIPS OpenSSL
components/openssl/README
components/openssl/openssl-0.9.8-fips-140/Makefile
components/openssl/openssl-0.9.8-fips-140/ccwrap.sh
components/openssl/openssl-0.9.8-fips-140/engines/pkcs11/e_pk11.c
components/openssl/openssl-0.9.8-fips-140/engines/pkcs11/e_pk11.h
components/openssl/openssl-0.9.8-fips-140/engines/pkcs11/e_pk11_err.c
components/openssl/openssl-0.9.8-fips-140/engines/pkcs11/e_pk11_err.h
components/openssl/openssl-0.9.8-fips-140/engines/pkcs11/e_pk11_pub.c
components/openssl/openssl-0.9.8-fips-140/engines/pkcs11/e_pk11_uri.c
components/openssl/openssl-0.9.8-fips-140/engines/pkcs11/e_pk11_uri.h
components/openssl/openssl-0.9.8-fips-140/llib-lcrypto
components/openssl/openssl-0.9.8-fips-140/llib-lssl
components/openssl/openssl-0.9.8-fips-140/openssl-0.9.8-fips-140.license
components/openssl/openssl-0.9.8-fips-140/openssl-0.9.8-fips-140.p5m
components/openssl/openssl-0.9.8-fips-140/patches-post-config/opensslconf.patch
components/openssl/openssl-0.9.8-fips-140/patches/08-6193522.patch
components/openssl/openssl-0.9.8-fips-140/patches/11-6546806.patch
components/openssl/openssl-0.9.8-fips-140/patches/15-pkcs11_engine-0.9.8a.patch
components/openssl/openssl-0.9.8-fips-140/patches/18-compiler_opts.patch
components/openssl/openssl-0.9.8-fips-140/patches/20-remove_rpath.patch
components/openssl/openssl-0.9.8-fips-140/patches/23-noexstack.patch
components/openssl/openssl-0.9.8-fips-140/patches/25-fips_rand.patch
components/openssl/openssl-0.9.8-fips-140/patches/26-openssl_fips.patch
components/openssl/openssl-0.9.8-fips-140/patches/27-6978791.patch
components/openssl/openssl-0.9.8-fips-140/patches/28-enginesdir.patch
components/openssl/openssl-0.9.8-fips-140/patches/sparc-01-ccwrap.patch
components/openssl/openssl-0.9.8-fips-140/resolve.deps
components/openssl/openssl-1.0.1-fips-140/Makefile
components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11.c
components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11.h
components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_err.c
components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_err.h
components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_pub.c
components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_uri.c
components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_uri.h
components/openssl/openssl-1.0.1-fips-140/llib-lcrypto
components/openssl/openssl-1.0.1-fips-140/llib-lssl
components/openssl/openssl-1.0.1-fips-140/openssl-1.0.1-fips-140.license
components/openssl/openssl-1.0.1-fips-140/openssl-1.0.1-fips-140.p5m
components/openssl/openssl-1.0.1-fips-140/patches-post-config/opensslconf.patch
components/openssl/openssl-1.0.1-fips-140/patches/08-6193522.patch
components/openssl/openssl-1.0.1-fips-140/patches/11-6546806.patch
components/openssl/openssl-1.0.1-fips-140/patches/15-pkcs11_engine-0.9.8a.patch
components/openssl/openssl-1.0.1-fips-140/patches/18-compiler_opts.patch
components/openssl/openssl-1.0.1-fips-140/patches/20-remove_rpath.patch
components/openssl/openssl-1.0.1-fips-140/patches/23-noexstack.patch
components/openssl/openssl-1.0.1-fips-140/patches/26-openssl_fips.patch
components/openssl/openssl-1.0.1-fips-140/patches/27-6978791.patch
components/openssl/openssl-1.0.1-fips-140/patches/28-enginesdir.patch
components/openssl/openssl-1.0.1-fips-140/patches/32_aes_cbc_len_check.patch
components/openssl/openssl-1.0.1-fips-140/patches/33_cert_chain.patch
components/openssl/openssl-1.0.1-fips-140/patches/34_tls_segfault.patch
components/openssl/openssl-1.0.1-fips-140/resolve.deps
components/openssl/openssl-1.0.1/Makefile
components/openssl/openssl-1.0.1/openssl-1.0.1.p5m
components/openssl/openssl-1.0.1/patches/31_dtls_version.patch
components/openssl/openssl-1.0.1/patches/33_cert_chain.patch
components/openssl/openssl-1.0.1/patches/34_tls_segfault.patch
components/openssl/openssl-1.0.1/patches/openssl-t4-inline.sparc-patch
components/openssl/openssl-fips/Makefile
--- a/components/openssl/README	Mon Jan 27 23:00:15 2014 -0800
+++ b/components/openssl/README	Wed Jan 29 11:12:07 2014 -0800
@@ -24,10 +24,10 @@
 Build Layout
 ---
 
-OpenSSL build is run four times. Once for regular dynamic 1.0.0 non-fips, once 
-for static 1.0.0 bits to link with standalone wanboot binary, once for 0.9.8
-fips-140, and once for 0.9.8 FIPS-140 canister (in the openssl-fips component)
-needed to build 0.9.8 FIPS-140 certified libraries. All builds apart from 
+OpenSSL build is run four times. Once for regular dynamic 1.0.1 non-fips, once 
+for static 1.0.1 bits to link with standalone wanboot binary, once for 1.0.1
+fips-140, and once for 1.0.1 FIPS-140 canister (in the openssl-fips component)
+needed to build 1.0.1 FIPS-140 certified libraries. All builds apart from 
 static libraries for wanboot are done for 32 and 64 bits. So, in total, OpenSSL
 is built seven times. OpenSSL for wanboot is only build on sparc.
 
@@ -138,23 +138,16 @@
 The fips Build
 ---
 
-FIPS-140 certified libraries for Solaris private use. We wait for OpenSSL 1.0.0
-to be FIPS-140 certified in which time we can ship only 1.0.0 with S11 and make
-it a public interface.
+FIPS-140 certified libraries for Solaris private use. We wait for OpenSSL 1.0.1
+to be FIPS-140 certified in which time we can ship only 1.0.1 with S11 and make
+it a public interface. (To be done next)
 
 Patches
 ---
 
-All the patches from 1.0.0 are used in 0.9.8 as well aside from
-14-manpage_openssl.patch which is not needed since we do not deliver 0.9.8 man
-pages. Additional patches:
-
-01-7009105.patch
-Fixing a bug introduces in 0.9.8q and fixed in 0.9.8r.
-
-sparc-01-ccwrap.patch
-Workaround so that fingerprinting the canister during runtime and comparing it
-with the saved fingerprint works correctly.
+All the patches from 1.0.1 (non-fips) are used in 1.0.1 (fips) as well aside from
+14-manpage_openssl.patch which is not needed since we do not deliver 1.0.1 man
+pages.  Once we make fips version public, we should deliver man page.
 
 The wanboot Build
 ----
--- a/components/openssl/openssl-0.9.8-fips-140/Makefile	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
-#
-export PARFAIT_BUILD=no
-
-include ../../../make-rules/shared-macros.mk
-
-PATH=$(SPRO_VROOT)/bin:/usr/bin:/usr/gnu/bin:/usr/perl5/bin
-
-COMPONENT_NAME =	openssl-fips-140
-# Note that this is the OpenSSL version that is used to build FIPS-140 certified
-# libraries. However, we use the FIPS canister version for the IPS package.
-COMPONENT_VERSION =	0.9.8y
-IPS_COMPONENT_VERSION = 1.2
-COMPONENT_PROJECT_URL=	http://www.openssl.org/
-COMPONENT_SRC_NAME =	openssl
-COMPONENT_SRC =		$(COMPONENT_SRC_NAME)-$(COMPONENT_VERSION)
-COMPONENT_ARCHIVE =	$(COMPONENT_SRC).tar.gz
-COMPONENT_ARCHIVE_HASH=	\
-    sha256:bbecf13495e612936e3a9860c29c0701413564b7a964bf771a3575eaa867cee3
-COMPONENT_ARCHIVE_URL =	$(COMPONENT_PROJECT_URL)source/$(COMPONENT_ARCHIVE)
-COMPONENT_BUGDB=	utility/openssl
-
-# Apply the patch on SPARC only. Must put this before including prep.mk as
-# mentioned in there.
-PATCH_sparc = patches/sparc-01-ccwrap.patch
-EXTRA_PATCHES = $(PATCH_$(MACH))
-# Note that the SPARC patch above does not fit this pattern. That is intentional
-# and a reason why we can add it to the EXTRA_PATCHES variable so that we use it
-# only on SPARC.
-PATCH_PATTERN = [0-9][0-9]*.patch
-
-include $(WS_TOP)/make-rules/prep.mk
-include $(WS_TOP)/make-rules/configure.mk
-include $(WS_TOP)/make-rules/ips.mk
-include $(WS_TOP)/make-rules/lint-libraries.mk
-
-# OpenSSL does not use autoconf but its own configure system.
-CONFIGURE_SCRIPT = $(SOURCE_DIR)/Configure
-
-# Used in the configure options below.
-PKCS11_LIB32 = /usr/lib/libpkcs11.so.1
-PKCS11_LIB64 = /usr/lib/64/libpkcs11.so.1
-ENGINESDIR_32 = /lib/openssl/engines
-ENGINESDIR_64 = /lib/openssl/engines/64
-
-# Built openssl/openssl-fips component is used when building FIPS-140 libraries.
-# What we do here follows the OpenSSL FIPS-140 User Guide instructions.
-FIPS_BUILD_DIR_32 = $(shell echo $(BUILD_DIR_32) | \
-    sed -e 's/openssl-0.9.8-fips-140/openssl-fips/g' )
-FIPS_BUILD_DIR_64 = $(shell echo $(BUILD_DIR_64) | \
-    sed -e 's/openssl-0.9.8-fips-140/openssl-fips/g' )
-
-CONFIGURE_OPTIONS =  -DSOLARIS_OPENSSL -DNO_WINDOWS_BRAINDEATH
-CONFIGURE_OPTIONS += --openssldir=/etc/openssl
-CONFIGURE_OPTIONS += --prefix=/usr
-# We use OpenSSL install code for installing only manual pages and we do that
-# for 32-bit version only.
-CONFIGURE_OPTIONS += --install_prefix=$(PROTO_DIR)
-CONFIGURE_OPTIONS += no-ec
-CONFIGURE_OPTIONS += no-ecdh
-CONFIGURE_OPTIONS += no-ecdsa
-CONFIGURE_OPTIONS += no-rc3
-CONFIGURE_OPTIONS += no-rc5
-CONFIGURE_OPTIONS += no-mdc2
-CONFIGURE_OPTIONS += no-idea
-CONFIGURE_OPTIONS += no-hw_4758_cca
-CONFIGURE_OPTIONS += no-hw_aep
-CONFIGURE_OPTIONS += no-hw_atalla
-CONFIGURE_OPTIONS += no-hw_chil
-CONFIGURE_OPTIONS += no-hw_gmp
-CONFIGURE_OPTIONS += no-hw_ncipher
-CONFIGURE_OPTIONS += no-hw_nuron
-CONFIGURE_OPTIONS += no-hw_padlock
-CONFIGURE_OPTIONS += no-hw_sureware
-CONFIGURE_OPTIONS += no-hw_ubsec
-CONFIGURE_OPTIONS += no-hw_cswift
-CONFIGURE_OPTIONS += threads
-CONFIGURE_OPTIONS += shared
-CONFIGURE_OPTIONS += fips --with-fipslibdir="$(FIPS_BUILD_DIR_$(BITS))/fips"
-
-# We define our own compiler and linker option sets for Solaris. See Configure
-# for more information.
-CONFIGURE_OPTIONS32_i386 =	solaris-x86-cc-sunw
-CONFIGURE_OPTIONS32_sparc =	solaris-sparcv8-cc-sunw
-CONFIGURE_OPTIONS64_i386 =	solaris64-x86_64-cc-sunw
-CONFIGURE_OPTIONS64_sparc =	solaris64-sparcv9-cc-sunw
-
-# Some additional options needed for our engines.
-CONFIGURE_OPTIONS += --pk11-libname=$(PKCS11_LIB$(BITS))
-CONFIGURE_OPTIONS += --enginesdir=$(ENGINESDIR_$(BITS))
-CONFIGURE_OPTIONS += $(CONFIGURE_OPTIONS$(BITS)_$(MACH))
-
-# OpenSSL has its own configure system which must be run from the fully
-# populated source code directory. However, the Userland configuration phase is
-# run from the build directory. The easiest way to workaround it is to copy all
-# the source files there.
-COMPONENT_PRE_CONFIGURE_ACTION = \
-    ( $(CLONEY) $(SOURCE_DIR) $(BUILD_DIR)/$(MACH$(BITS)); )
-
-# We deliver only one opensslconf.h file which must be suitable for both 32 and
-# 64 bits. Depending on the configuration option, OpenSSL's Configure script
-# creates opensslconf.h for either 32 or 64 bits. A patch makes the resulting
-# header file usable on both architectures. The patch was generated against the
-# opensslconf.h version from the 32 bit build.
-COMPONENT_POST_CONFIGURE_ACTION = \
-    ( [ $(BITS) -eq 32 ] && $(GPATCH) -p1 $(@D)/crypto/opensslconf.h \
-      patches-post-config/opensslconf.patch; cd $(@D); $(MAKE) depend; )
-
-# We must make sure that openssl-fips component is built before this 0.9.8
-# component since in order to build FIPS-140 certified libraries, the canister
-# is needed. Note that we must unset BITS that would override the same variable
-# used in openssl-fips' Makefile, and we would end up up with both canisters
-# built in 64 (or 32) bits.
-$(COMPONENT_DIR)/../openssl-fips/build/$(MACH32)/.installed \
-$(COMPONENT_DIR)/../openssl-fips/build/$(MACH64)/.installed:
-	( unset BITS; \
-	$(MAKE) -C $(COMPONENT_DIR)/../openssl-fips install; )
-
-# download, clean, and clobber should all propogate to the fips bits
-download clobber clean::
-	(cd ../openssl-fips ; $(GMAKE) [email protected])
-
-# We do not ship our engines as patches since it would be more difficult to
-# update the files which have been under continuous development. We rather copy
-# the files to the right directories and let OpenSSL makefiles build it.
-COMPONENT_PRE_BUILD_ACTION = \
-    ( $(LN) -fs $(COMPONENT_DIR)/engines/pkcs11/*     $(@D)/engines; ) 
-
-# OpenSSL does not install into <dir>/$(MACH64) for 64-bit install so no such
-# directory is created and Userland install code would fail when installing lint
-# libraries.
-COMPONENT_PRE_INSTALL_ACTION = ( $(MKDIR) $(PROTO_DIR)/usr/lib/$(MACH64); )
-
-# For ccwrap on SPARC. This is to workaround a problem with the cc compiler on
-# SPARC. We must modify PATH so that the wrapper can be found when run from
-# fips/fipsld.
-COMPONENT_BUILD_ENV += PATH=$(COMPONENT_DIR):$(PATH)
-COMPONENT_INSTALL_ENV += PATH=$(COMPONENT_DIR):$(PATH)
-
-$(SOURCE_DIR)/.prep: $(COMPONENT_DIR)/../openssl-fips/build/$(MACH32)/.installed \
-		     $(COMPONENT_DIR)/../openssl-fips/build/$(MACH64)/.installed
-
-# We need ccwrap for building the libraries.
-$(BUILD_32_and_64):	ccwrap
-build:			$(BUILD_32_and_64)
-
-CLOBBER_PATHS += ccwrap
-
-# We follow what we do for install in openssl/openssl-1.0.0 component. Please
-# see the comment in Makefile in there for more information.
-install:	$(INSTALL_32_and_64)
-
-# We need to modify the default lint flags to include patched opensslconf.h from
-# the build directory. If we do not do that, lint will complain about md2.h
-# which is not enabled by default but it is in our opensslconf.h.
-LFLAGS_32 := -I$(BUILD_DIR_32)/include $(LINT_FLAGS)
-LFLAGS_64 := -I$(BUILD_DIR_64)/include $(LINT_FLAGS)
-
-# Set modified lint flags for our lint library targets.
-$(BUILD_DIR_32)/llib-lcrypto.ln: LINT_FLAGS=$(LFLAGS_32)
-$(BUILD_DIR_32)/llib-lssl.ln: LINT_FLAGS=$(LFLAGS_32)
-$(BUILD_DIR_64)/llib-lcrypto.ln: LINT_FLAGS=$(LFLAGS_64)
-$(BUILD_DIR_64)/llib-lssl.ln: LINT_FLAGS=$(LFLAGS_64)
-
-test:		$(NO_TESTS)
-
-BUILD_PKG_DEPENDENCIES =	$(BUILD_TOOLS)
-
-include $(WS_TOP)/make-rules/depend.mk
--- a/components/openssl/openssl-0.9.8-fips-140/ccwrap.sh	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-#!/bin/sh
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
-#
-
-# Very simple cc wrapper whose only purpose is to ensure that cc behaves as
-# desired when linking the fipscanister.o object. Currently that means removing
-# "-g" and adding "-W2,-Rfully_unroll" from/to the compiler options.
-#
-# This wrapper is called from fipsld. See fips/fipsld and
-# patches/sparc-01-ccwrap.patch for more information.
-
-CC_CMD=""
-while [ $# -ne 0 ]; do
-	if [ "$1" != "-g" ]; then
-		CC_CMD="$CC_CMD '$1'"
-	fi
-	shift;
-done
-
-eval $CC_CMD -W2,-Rfully_unroll
--- a/components/openssl/openssl-0.9.8-fips-140/engines/pkcs11/e_pk11.c	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3714 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- *
- */
-
-/* crypto/engine/e_pk11.c */
-/*
- * This product includes software developed by the OpenSSL Project for
- * use in the OpenSSL Toolkit (http://www.openssl.org/).
- *
- * This project also referenced hw_pkcs11-0.9.7b.patch written by
- * Afchine Madjlessi.
- */
-/*
- * ====================================================================
- * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    [email protected]
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <strings.h>
-
-#include <openssl/e_os2.h>
-#include <openssl/crypto.h>
-#include <openssl/engine.h>
-#include <openssl/dso.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-#include <openssl/md5.h>
-#include <openssl/pem.h>
-#ifndef OPENSSL_NO_RSA
-#include <openssl/rsa.h>
-#endif
-#ifndef OPENSSL_NO_DSA
-#include <openssl/dsa.h>
-#endif
-#ifndef OPENSSL_NO_DH
-#include <openssl/dh.h>
-#endif
-#include <openssl/rand.h>
-#include <openssl/objects.h>
-#include <openssl/x509.h>
-#include <openssl/aes.h>
-#include <dlfcn.h>
-#include <pthread.h>
-
-#ifndef OPENSSL_NO_HW
-#ifndef OPENSSL_NO_HW_PK11
-
-/* label for debug messages printed on stderr */
-#define	PK11_DBG	"PKCS#11 ENGINE DEBUG"
-/* prints a lot of debug messages on stderr about slot selection process */
-#undef	DEBUG_SLOT_SELECTION
-/*
- * Solaris specific code. See comment at check_hw_mechanisms() for more
- * information.
- */
-#if defined(__SVR4) && defined(__sun)
-#define	SOLARIS_HW_SLOT_SELECTION
-#endif
-
-#ifdef DEBUG_SLOT_SELECTION
-#define	DEBUG_SLOT_SEL(...) fprintf(stderr, __VA_ARGS__)
-#else
-#define	DEBUG_SLOT_SEL(...)
-#endif
-
-/*
- * AES counter mode is not supported in the OpenSSL EVP API yet and neither
- * there are official OIDs for mechanisms based on this mode. With our changes,
- * an application can define its own EVP calls for AES counter mode and then
- * it can make use of hardware acceleration through this engine. However, it's
- * better if we keep AES CTR support code under ifdef's.
- */
-#define	SOLARIS_AES_CTR
-
-#include <security/cryptoki.h>
-#include <security/pkcs11.h>
-#include "e_pk11.h"
-#include "e_pk11_uri.h"
-
-static CK_BBOOL pk11_true = CK_TRUE;
-static CK_BBOOL pk11_false = CK_FALSE;
-#define	PK11_ENGINE_LIB_NAME "PKCS#11 engine"
-#include "e_pk11_err.c"
-#include "e_pk11_uri.c"
-#include "e_pk11_pub.c"
-
-#ifdef	SOLARIS_AES_CTR
-/*
- * NIDs for AES counter mode that will be defined during the engine
- * initialization.
- */
-int NID_aes_128_ctr = NID_undef;
-int NID_aes_192_ctr = NID_undef;
-int NID_aes_256_ctr = NID_undef;
-#endif	/* SOLARIS_AES_CTR */
-
-/*
- * We use this lock to prevent multiple C_Login()s, guard getpassphrase(),
- * uri_struct manipulation, and static token info. All of that is used by the
- * RSA keys by reference feature.
- */
-pthread_mutex_t *uri_lock;
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-/*
- * Tables for symmetric ciphers and digest mechs found in the pkcs11_kernel
- * library. See comment at check_hw_mechanisms() for more information.
- */
-int *hw_cnids;
-int *hw_dnids;
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-
-/* PKCS#11 session caches and their locks for all operation types */
-static PK11_CACHE session_cache[OP_MAX];
-
-/*
- * We cache the flags so that we do not have to run C_GetTokenInfo() again when
- * logging into the token.
- */
-CK_FLAGS pubkey_token_flags;
-
-/*
- * As stated in v2.20, 11.7 Object Management Function, in section for
- * C_FindObjectsInit(), at most one search operation may be active at a given
- * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
- * grouped together to form one atomic search operation. This is already
- * ensured by the property of unique PKCS#11 session handle used for each
- * PK11_SESSION object.
- *
- * This is however not the biggest concern - maintaining consistency of the
- * underlying object store is more important. The same section of the spec also
- * says that one thread can be in the middle of a search operation while another
- * thread destroys the object matching the search template which would result in
- * invalid handle returned from the search operation.
- *
- * Hence, the following locks are used for both protection of the object stores.
- * They are also used for active list protection.
- */
-pthread_mutex_t *find_lock[OP_MAX] = { NULL };
-
-/*
- * lists of asymmetric key handles which are active (referenced by at least one
- * PK11_SESSION structure, either held by a thread or present in free_session
- * list) for given algorithm type
- */
-PK11_active *active_list[OP_MAX] = { NULL };
-
-/*
- * Create all secret key objects in a global session so that they are available
- * to use for other sessions. These other sessions may be opened or closed
- * without losing the secret key objects.
- */
-static CK_SESSION_HANDLE	global_session = CK_INVALID_HANDLE;
-
-/* Index for the supported ciphers */
-enum pk11_cipher_id {
-	PK11_DES_CBC,
-	PK11_DES3_CBC,
-	PK11_DES_ECB,
-	PK11_DES3_ECB,
-	PK11_RC4,
-	PK11_AES_128_CBC,
-	PK11_AES_192_CBC,
-	PK11_AES_256_CBC,
-	PK11_AES_128_ECB,
-	PK11_AES_192_ECB,
-	PK11_AES_256_ECB,
-	PK11_BLOWFISH_CBC,
-#ifdef	SOLARIS_AES_CTR
-	PK11_AES_128_CTR,
-	PK11_AES_192_CTR,
-	PK11_AES_256_CTR,
-#endif	/* SOLARIS_AES_CTR */
-	PK11_CIPHER_MAX
-};
-
-/* Index for the supported digests */
-enum pk11_digest_id {
-	PK11_MD5,
-	PK11_SHA1,
-	PK11_SHA224,
-	PK11_SHA256,
-	PK11_SHA384,
-	PK11_SHA512,
-	PK11_DIGEST_MAX
-};
-
-typedef struct PK11_CIPHER_st
-	{
-	enum pk11_cipher_id	id;
-	int			nid;
-	int			iv_len;
-	int			min_key_len;
-	int			max_key_len;
-	CK_KEY_TYPE		key_type;
-	CK_MECHANISM_TYPE	mech_type;
-	} PK11_CIPHER;
-
-typedef struct PK11_DIGEST_st
-	{
-	enum pk11_digest_id	id;
-	int			nid;
-	CK_MECHANISM_TYPE	mech_type;
-	} PK11_DIGEST;
-
-/* ENGINE level stuff */
-static int pk11_init(ENGINE *e);
-static int pk11_library_init(ENGINE *e);
-static int pk11_finish(ENGINE *e);
-static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
-static int pk11_destroy(ENGINE *e);
-
-/* RAND stuff */
-static void pk11_rand_seed(const void *buf, int num);
-static void pk11_rand_add(const void *buf, int num, double add_entropy);
-static void pk11_rand_cleanup(void);
-static int pk11_rand_bytes(unsigned char *buf, int num);
-static int pk11_rand_status(void);
-
-/* These functions are also used in other files */
-PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
-void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
-
-/* active list manipulation functions used in this file */
-extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
-extern void pk11_free_active_list(PK11_OPTYPE type);
-
-#ifndef OPENSSL_NO_RSA
-int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
-int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
-int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
-#endif
-#ifndef OPENSSL_NO_DSA
-int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
-int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
-int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
-#endif
-#ifndef OPENSSL_NO_DH
-int pk11_destroy_dh_key_objects(PK11_SESSION *session);
-int pk11_destroy_dh_object(PK11_SESSION *session, CK_BBOOL uselock);
-#endif
-
-/* Local helper functions */
-static int pk11_free_all_sessions(void);
-static int pk11_free_session_list(PK11_OPTYPE optype);
-static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
-static int pk11_destroy_cipher_key_objects(PK11_SESSION *session);
-static int pk11_destroy_object(CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE oh,
-    CK_BBOOL persistent);
-static const char *get_PK11_LIBNAME(void);
-static void free_PK11_LIBNAME(void);
-static long set_PK11_LIBNAME(const char *name);
-
-/* Symmetric cipher and digest support functions */
-static int cipher_nid_to_pk11(int nid);
-#ifdef	SOLARIS_AES_CTR
-static int pk11_add_NID(char *sn, char *ln);
-static int pk11_add_aes_ctr_NIDs(void);
-#endif	/* SOLARIS_AES_CTR */
-static int pk11_usable_ciphers(const int **nids);
-static int pk11_usable_digests(const int **nids);
-static int pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-	const unsigned char *iv, int enc);
-static int pk11_cipher_final(PK11_SESSION *sp);
-static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-	const unsigned char *in, unsigned int inl);
-static int pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx);
-static int pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-	const int **nids, int nid);
-static int pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
-	const int **nids, int nid);
-static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
-	const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp);
-static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
-	int key_len);
-static int md_nid_to_pk11(int nid);
-static int pk11_digest_init(EVP_MD_CTX *ctx);
-static int pk11_digest_update(EVP_MD_CTX *ctx, const void *data,
-	size_t count);
-static int pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
-static int pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
-static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
-
-static int pk11_choose_slots(int *any_slot_found);
-static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
-    CK_SLOT_ID current_slot, int *current_slot_n_cipher,
-    int *local_cipher_nids);
-static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
-    CK_SLOT_ID current_slot, int *current_slot_n_digest,
-    int *local_digest_nids);
-static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR, int slot_id,
-    int *current_slot_n_cipher, int *local_cipher_nids,
-    PK11_CIPHER *cipher);
-static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
-    int *current_slot_n_digest, int *local_digest_nids,
-    PK11_DIGEST *digest);
-
-static int pk11_init_all_locks(void);
-static void pk11_free_all_locks(void);
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-static int check_hw_mechanisms(void);
-static int nid_in_table(int nid, int *nid_table);
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-
-#define	TRY_OBJ_DESTROY(sp, obj_hdl, retval, uselock, alg_type)	\
-	{								\
-	if (uselock)							\
-		LOCK_OBJSTORE(alg_type);				\
-	if (pk11_active_delete(obj_hdl, alg_type) == 1)			\
-		{							\
-		retval = pk11_destroy_object(sp->session, obj_hdl,	\
-		    sp->persistent);					\
-		}							\
-	if (uselock)							\
-		UNLOCK_OBJSTORE(alg_type);				\
-	}
-
-static int cipher_nids[PK11_CIPHER_MAX];
-static int digest_nids[PK11_DIGEST_MAX];
-static int cipher_count		= 0;
-static int digest_count		= 0;
-static CK_BBOOL pk11_have_rsa	= CK_FALSE;
-static CK_BBOOL pk11_have_dsa	= CK_FALSE;
-static CK_BBOOL pk11_have_dh	= CK_FALSE;
-static CK_BBOOL pk11_have_random = CK_FALSE;
-
-/*
- * Static list of ciphers.
- * Note, that ciphers array is indexed by member PK11_CIPHER.id,
- * thus ciphers[i].id == i
- * Rows must be kept in sync with enum pk11_cipher_id.
- */
-static PK11_CIPHER ciphers[] =
-	{
-	{ PK11_DES_CBC,		NID_des_cbc,		8,	 8,   8,
-		CKK_DES,	CKM_DES_CBC, },
-	{ PK11_DES3_CBC,	NID_des_ede3_cbc,	8,	24,  24,
-		CKK_DES3,	CKM_DES3_CBC, },
-	{ PK11_DES_ECB,		NID_des_ecb,		0,	 8,   8,
-		CKK_DES,	CKM_DES_ECB, },
-	{ PK11_DES3_ECB,	NID_des_ede3_ecb,	0,	24,  24,
-		CKK_DES3,	CKM_DES3_ECB, },
-	{ PK11_RC4,		NID_rc4,		0,	16, 256,
-		CKK_RC4,	CKM_RC4, },
-	{ PK11_AES_128_CBC,	NID_aes_128_cbc,	16,	16,  16,
-		CKK_AES,	CKM_AES_CBC, },
-	{ PK11_AES_192_CBC,	NID_aes_192_cbc,	16,	24,  24,
-		CKK_AES,	CKM_AES_CBC, },
-	{ PK11_AES_256_CBC,	NID_aes_256_cbc,	16,	32,  32,
-		CKK_AES,	CKM_AES_CBC, },
-	{ PK11_AES_128_ECB,	NID_aes_128_ecb,	0,	16,  16,
-		CKK_AES,	CKM_AES_ECB, },
-	{ PK11_AES_192_ECB,	NID_aes_192_ecb,	0,	24,  24,
-		CKK_AES,	CKM_AES_ECB, },
-	{ PK11_AES_256_ECB,	NID_aes_256_ecb,	0,	32,  32,
-		CKK_AES,	CKM_AES_ECB, },
-	{ PK11_BLOWFISH_CBC,	NID_bf_cbc,		8,	16,  16,
-		CKK_BLOWFISH,	CKM_BLOWFISH_CBC, },
-#ifdef	SOLARIS_AES_CTR
-	/* we don't know the correct NIDs until the engine is initialized */
-	{ PK11_AES_128_CTR,	NID_undef,		16,	16,  16,
-		CKK_AES,	CKM_AES_CTR, },
-	{ PK11_AES_192_CTR,	NID_undef,		16,	24,  24,
-		CKK_AES,	CKM_AES_CTR, },
-	{ PK11_AES_256_CTR,	NID_undef,		16,	32,  32,
-		CKK_AES,	CKM_AES_CTR, },
-#endif	/* SOLARIS_AES_CTR */
-	};
-
-/*
- * Static list of digests.
- * Note, that digests array is indexed by member PK11_DIGEST.id,
- * thus digests[i].id == i
- * Rows must be kept in sync with enum pk11_digest_id.
- */
-static PK11_DIGEST digests[] =
-	{
-	{PK11_MD5,	NID_md5,	CKM_MD5, },
-	{PK11_SHA1,	NID_sha1,	CKM_SHA_1, },
-	{PK11_SHA224,	NID_sha224,	CKM_SHA224, },
-	{PK11_SHA256,	NID_sha256,	CKM_SHA256, },
-	{PK11_SHA384,	NID_sha384,	CKM_SHA384, },
-	{PK11_SHA512,	NID_sha512,	CKM_SHA512, },
-	{0,		NID_undef,	0xFFFF, },
-	};
-
-/*
- * Structure to be used for the cipher_data/md_data in
- * EVP_CIPHER_CTX/EVP_MD_CTX structures in order to use the same pk11
- * session in multiple cipher_update calls
- */
-typedef struct PK11_CIPHER_STATE_st
-	{
-	PK11_SESSION	*sp;
-	} PK11_CIPHER_STATE;
-
-
-/*
- * libcrypto EVP stuff - this is how we get wired to EVP so the engine gets
- * called when libcrypto requests a cipher NID.
- *
- * Note how the PK11_CIPHER_STATE is used here.
- */
-
-/* DES CBC EVP */
-static const EVP_CIPHER pk11_des_cbc =
-	{
-	NID_des_cbc,
-	8, 8, 8,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-/* 3DES CBC EVP */
-static const EVP_CIPHER pk11_3des_cbc =
-	{
-	NID_des_ede3_cbc,
-	8, 24, 8,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-/*
- * ECB modes don't use an Initial Vector so that's why set_asn1_parameters and
- * get_asn1_parameters fields are set to NULL.
- */
-static const EVP_CIPHER pk11_des_ecb =
-	{
-	NID_des_ecb,
-	8, 8, 8,
-	EVP_CIPH_ECB_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_3des_ecb =
-	{
-	NID_des_ede3_ecb,
-	8, 24, 8,
-	EVP_CIPH_ECB_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-
-static const EVP_CIPHER pk11_aes_128_cbc =
-	{
-	NID_aes_128_cbc,
-	16, 16, 16,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_aes_192_cbc =
-	{
-	NID_aes_192_cbc,
-	16, 24, 16,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_aes_256_cbc =
-	{
-	NID_aes_256_cbc,
-	16, 32, 16,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-/*
- * ECB modes don't use IV so that's why set_asn1_parameters and
- * get_asn1_parameters are set to NULL.
- */
-static const EVP_CIPHER pk11_aes_128_ecb =
-	{
-	NID_aes_128_ecb,
-	16, 16, 0,
-	EVP_CIPH_ECB_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_aes_192_ecb =
-	{
-	NID_aes_192_ecb,
-	16, 24, 0,
-	EVP_CIPH_ECB_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_aes_256_ecb =
-	{
-	NID_aes_256_ecb,
-	16, 32, 0,
-	EVP_CIPH_ECB_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-#ifdef	SOLARIS_AES_CTR
-/*
- * NID_undef's will be changed to the AES counter mode NIDs as soon they are
- * created in pk11_library_init(). Note that the need to change these structures
- * is the reason why we don't define them with the const keyword.
- */
-static EVP_CIPHER pk11_aes_128_ctr =
-	{
-	NID_undef,
-	16, 16, 16,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static EVP_CIPHER pk11_aes_192_ctr =
-	{
-	NID_undef,
-	16, 24, 16,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static EVP_CIPHER pk11_aes_256_ctr =
-	{
-	NID_undef,
-	16, 32, 16,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-#endif	/* SOLARIS_AES_CTR */
-
-static const EVP_CIPHER pk11_bf_cbc =
-	{
-	NID_bf_cbc,
-	8, 16, 8,
-	EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_rc4 =
-	{
-	NID_rc4,
-	1, 16, 0,
-	EVP_CIPH_VARIABLE_LENGTH,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-static const EVP_MD pk11_md5 =
-	{
-	NID_md5,
-	NID_md5WithRSAEncryption,
-	MD5_DIGEST_LENGTH,
-	0,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	MD5_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-static const EVP_MD pk11_sha1 =
-	{
-	NID_sha1,
-	NID_sha1WithRSAEncryption,
-	SHA_DIGEST_LENGTH,
-	0,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	SHA_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-static const EVP_MD pk11_sha224 =
-	{
-	NID_sha224,
-	NID_sha224WithRSAEncryption,
-	SHA224_DIGEST_LENGTH,
-	0,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	/* SHA-224 uses the same cblock size as SHA-256 */
-	SHA256_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-static const EVP_MD pk11_sha256 =
-	{
-	NID_sha256,
-	NID_sha256WithRSAEncryption,
-	SHA256_DIGEST_LENGTH,
-	0,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	SHA256_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-static const EVP_MD pk11_sha384 =
-	{
-	NID_sha384,
-	NID_sha384WithRSAEncryption,
-	SHA384_DIGEST_LENGTH,
-	0,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	/* SHA-384 uses the same cblock size as SHA-512 */
-	SHA512_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-static const EVP_MD pk11_sha512 =
-	{
-	NID_sha512,
-	NID_sha512WithRSAEncryption,
-	SHA512_DIGEST_LENGTH,
-	0,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	SHA512_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-/*
- * Initialization function. Sets up various PKCS#11 library components.
- * The definitions for control commands specific to this engine
- */
-#define	PK11_CMD_SO_PATH		ENGINE_CMD_BASE
-static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
-	{
-		{
-		PK11_CMD_SO_PATH,
-		"SO_PATH",
-		"Specifies the path to the 'pkcs#11' shared library",
-		ENGINE_CMD_FLAG_STRING
-		},
-		{0, NULL, NULL, 0}
-	};
-
-
-static RAND_METHOD pk11_random =
-	{
-	pk11_rand_seed,
-	pk11_rand_bytes,
-	pk11_rand_cleanup,
-	pk11_rand_add,
-	pk11_rand_bytes,
-	pk11_rand_status
-	};
-
-
-/* Constants used when creating the ENGINE */
-static const char *engine_pk11_id = "pkcs11";
-static const char *engine_pk11_name = "PKCS #11 engine support";
-
-CK_FUNCTION_LIST_PTR pFuncList = NULL;
-static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
-
-/*
- * This is a static string constant for the DSO file name and the function
- * symbol names to bind to. We set it in the Configure script based on whether
- * this is 32 or 64 bit build.
- */
-static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
-
-/* Needed in e_pk11_pub.c as well so that's why it is not static. */
-CK_SLOT_ID pubkey_SLOTID = 0;
-static CK_SLOT_ID rand_SLOTID = 0;
-static CK_SLOT_ID SLOTID = 0;
-static CK_BBOOL pk11_library_initialized = CK_FALSE;
-static CK_BBOOL pk11_atfork_initialized = CK_FALSE;
-static int pk11_pid = 0;
-
-static DSO *pk11_dso = NULL;
-
-/* allocate and initialize all locks used by the engine itself */
-static int pk11_init_all_locks(void)
-	{
-	int type;
-
-#ifndef OPENSSL_NO_RSA
-	find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
-	if (find_lock[OP_RSA] == NULL)
-		goto malloc_err;
-	(void) pthread_mutex_init(find_lock[OP_RSA], NULL);
-#endif /* OPENSSL_NO_RSA */
-
-	if ((uri_lock = OPENSSL_malloc(sizeof (pthread_mutex_t))) == NULL)
-		goto malloc_err;
-	(void) pthread_mutex_init(uri_lock, NULL);
-
-#ifndef OPENSSL_NO_DSA
-	find_lock[OP_DSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
-	if (find_lock[OP_DSA] == NULL)
-		goto malloc_err;
-	(void) pthread_mutex_init(find_lock[OP_DSA], NULL);
-#endif /* OPENSSL_NO_DSA */
-
-#ifndef OPENSSL_NO_DH
-	find_lock[OP_DH] = OPENSSL_malloc(sizeof (pthread_mutex_t));
-	if (find_lock[OP_DH] == NULL)
-		goto malloc_err;
-	(void) pthread_mutex_init(find_lock[OP_DH], NULL);
-#endif /* OPENSSL_NO_DH */
-
-	for (type = 0; type < OP_MAX; type++)
-		{
-		session_cache[type].lock =
-		    OPENSSL_malloc(sizeof (pthread_mutex_t));
-		if (session_cache[type].lock == NULL)
-			goto malloc_err;
-		(void) pthread_mutex_init(session_cache[type].lock, NULL);
-		}
-
-	return (1);
-
-malloc_err:
-	pk11_free_all_locks();
-	PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
-	return (0);
-	}
-
-static void pk11_free_all_locks(void)
-	{
-	int type;
-
-#ifndef OPENSSL_NO_RSA
-	if (find_lock[OP_RSA] != NULL)
-		{
-		(void) pthread_mutex_destroy(find_lock[OP_RSA]);
-		OPENSSL_free(find_lock[OP_RSA]);
-		find_lock[OP_RSA] = NULL;
-		}
-#endif /* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-	if (find_lock[OP_DSA] != NULL)
-		{
-		(void) pthread_mutex_destroy(find_lock[OP_DSA]);
-		OPENSSL_free(find_lock[OP_DSA]);
-		find_lock[OP_DSA] = NULL;
-		}
-#endif /* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-	if (find_lock[OP_DH] != NULL)
-		{
-		(void) pthread_mutex_destroy(find_lock[OP_DH]);
-		OPENSSL_free(find_lock[OP_DH]);
-		find_lock[OP_DH] = NULL;
-		}
-#endif /* OPENSSL_NO_DH */
-
-	for (type = 0; type < OP_MAX; type++)
-		{
-		if (session_cache[type].lock != NULL)
-			{
-			(void) pthread_mutex_destroy(session_cache[type].lock);
-			OPENSSL_free(session_cache[type].lock);
-			session_cache[type].lock = NULL;
-			}
-		}
-	}
-
-/*
- * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
- */
-static int bind_pk11(ENGINE *e)
-	{
-#ifndef OPENSSL_NO_RSA
-	const RSA_METHOD *rsa = NULL;
-	RSA_METHOD *pk11_rsa = PK11_RSA();
-#endif	/* OPENSSL_NO_RSA */
-	if (!pk11_library_initialized)
-		if (!pk11_library_init(e))
-			return (0);
-
-	if (!ENGINE_set_id(e, engine_pk11_id) ||
-	    !ENGINE_set_name(e, engine_pk11_name) ||
-	    !ENGINE_set_ciphers(e, pk11_engine_ciphers) ||
-	    !ENGINE_set_digests(e, pk11_engine_digests))
-		return (0);
-#ifndef OPENSSL_NO_RSA
-	if (pk11_have_rsa == CK_TRUE)
-		{
-		if (!ENGINE_set_RSA(e, PK11_RSA()) ||
-		    !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
-		    !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
-			return (0);
-		DEBUG_SLOT_SEL("%s: registered RSA\n", PK11_DBG);
-		}
-#endif	/* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-	if (pk11_have_dsa == CK_TRUE)
-		{
-		if (!ENGINE_set_DSA(e, PK11_DSA()))
-			return (0);
-		DEBUG_SLOT_SEL("%s: registered DSA\n", PK11_DBG);
-		}
-#endif	/* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-	if (pk11_have_dh == CK_TRUE)
-		{
-		if (!ENGINE_set_DH(e, PK11_DH()))
-			return (0);
-		DEBUG_SLOT_SEL("%s: registered DH\n", PK11_DBG);
-		}
-#endif	/* OPENSSL_NO_DH */
-	if (pk11_have_random)
-		{
-		if (!ENGINE_set_RAND(e, &pk11_random))
-			return (0);
-		DEBUG_SLOT_SEL("%s: registered random\n", PK11_DBG);
-		}
-	if (!ENGINE_set_init_function(e, pk11_init) ||
-	    !ENGINE_set_destroy_function(e, pk11_destroy) ||
-	    !ENGINE_set_finish_function(e, pk11_finish) ||
-	    !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
-	    !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
-		return (0);
-
-/*
- * Apache calls OpenSSL function RSA_blinding_on() once during startup
- * which in turn calls bn_mod_exp. Since we do not implement bn_mod_exp
- * here, we wire it back to the OpenSSL software implementation.
- * Since it is used only once, performance is not a concern.
- */
-#ifndef OPENSSL_NO_RSA
-	rsa = RSA_PKCS1_SSLeay();
-	pk11_rsa->rsa_mod_exp = rsa->rsa_mod_exp;
-	pk11_rsa->bn_mod_exp = rsa->bn_mod_exp;
-#endif	/* OPENSSL_NO_RSA */
-
-	/* Ensure the pk11 error handling is set up */
-	ERR_load_pk11_strings();
-
-	return (1);
-	}
-
-static int bind_helper(ENGINE *e, const char *id)
-	{
-	if (id && (strcmp(id, engine_pk11_id) != 0))
-		return (0);
-
-	if (!bind_pk11(e))
-		return (0);
-
-	return (1);
-	}
-
-IMPLEMENT_DYNAMIC_CHECK_FN()
-IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
-
-/*
- * These are the static string constants for the DSO file name and
- * the function symbol names to bind to.
- */
-static const char *PK11_LIBNAME = NULL;
-
-static const char *get_PK11_LIBNAME(void)
-	{
-	if (PK11_LIBNAME)
-		return (PK11_LIBNAME);
-
-	return (def_PK11_LIBNAME);
-	}
-
-static void free_PK11_LIBNAME(void)
-	{
-	if (PK11_LIBNAME)
-		OPENSSL_free((void*)PK11_LIBNAME);
-
-	PK11_LIBNAME = NULL;
-	}
-
-static long set_PK11_LIBNAME(const char *name)
-	{
-	free_PK11_LIBNAME();
-
-	return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
-	}
-
-/* acquire all engine specific mutexes before fork */
-static void pk11_fork_prepare(void)
-	{
-	int i;
-
-	if (!pk11_library_initialized)
-		return;
-
-	LOCK_OBJSTORE(OP_RSA);
-	LOCK_OBJSTORE(OP_DSA);
-	LOCK_OBJSTORE(OP_DH);
-	(void) pthread_mutex_lock(uri_lock);
-	for (i = 0; i < OP_MAX; i++)
-		{
-		(void) pthread_mutex_lock(session_cache[i].lock);
-		}
-	}
-
-/* release all engine specific mutexes */
-static void pk11_fork_parent(void)
-	{
-	int i;
-
-	if (!pk11_library_initialized)
-		return;
-
-	for (i = OP_MAX - 1; i >= 0; i--)
-		{
-		(void) pthread_mutex_unlock(session_cache[i].lock);
-		}
-	UNLOCK_OBJSTORE(OP_DH);
-	UNLOCK_OBJSTORE(OP_DSA);
-	UNLOCK_OBJSTORE(OP_RSA);
-	(void) pthread_mutex_unlock(uri_lock);
-	}
-
-/*
- * same situation as in parent - we need to unlock all locks to make them
- * accessible to all threads.
- */
-static void pk11_fork_child(void)
-	{
-	int i;
-
-	if (!pk11_library_initialized)
-		return;
-
-	for (i = OP_MAX - 1; i >= 0; i--)
-		{
-		(void) pthread_mutex_unlock(session_cache[i].lock);
-		}
-	UNLOCK_OBJSTORE(OP_DH);
-	UNLOCK_OBJSTORE(OP_DSA);
-	UNLOCK_OBJSTORE(OP_RSA);
-	(void) pthread_mutex_unlock(uri_lock);
-	}
-
-/* Initialization function for the pk11 engine */
-static int pk11_init(ENGINE *e)
-{
-	return (pk11_library_init(e));
-}
-
-/*
- * Initialization function. Sets up various PKCS#11 library components.
- * It selects a slot based on predefined critiera. In the process, it also
- * count how many ciphers and digests to support. Since the cipher and
- * digest information is needed when setting default engine, this function
- * needs to be called before calling ENGINE_set_default.
- */
-/* ARGSUSED */
-static int pk11_library_init(ENGINE *e)
-	{
-	CK_C_GetFunctionList p;
-	CK_RV rv = CKR_OK;
-	CK_INFO info;
-	CK_ULONG ul_state_len;
-	int any_slot_found;
-	int i;
-
-	/*
-	 * pk11_library_initialized is set to 0 in pk11_finish() which is called
-	 * from ENGINE_finish(). However, if there is still at least one
-	 * existing functional reference to the engine (see engine(3) for more
-	 * information), pk11_finish() is skipped. For example, this can happen
-	 * if an application forgets to clear one cipher context. In case of a
-	 * fork() when the application is finishing the engine so that it can be
-	 * reinitialized in the child, forgotten functional reference causes
-	 * pk11_library_initialized to stay 1. In that case we need the PID
-	 * check so that we properly initialize the engine again.
-	 */
-	if (pk11_library_initialized)
-		{
-		if (pk11_pid == getpid())
-			{
-			return (1);
-			}
-		else
-			{
-			global_session = CK_INVALID_HANDLE;
-			/*
-			 * free the locks first to prevent memory leak in case
-			 * the application calls fork() without finishing the
-			 * engine first.
-			 */
-			pk11_free_all_locks();
-			}
-		}
-
-	if (pk11_dso == NULL)
-		{
-		PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-
-#ifdef	SOLARIS_AES_CTR
-	/*
-	 * We must do this before we start working with slots since we need all
-	 * NIDs there.
-	 */
-	if (pk11_add_aes_ctr_NIDs() == 0)
-		goto err;
-#endif	/* SOLARIS_AES_CTR */
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-	if (check_hw_mechanisms() == 0)
-		goto err;
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-
-	/* get the C_GetFunctionList function from the loaded library */
-	p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
-		PK11_GET_FUNCTION_LIST);
-	if (!p)
-		{
-		PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-
-	/* get the full function list from the loaded library */
-	rv = p(&pFuncList);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_Initialize(NULL_PTR);
-	if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
-		{
-		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_GetInfo(&info);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
-		goto err;
-		}
-
-	if (pk11_choose_slots(&any_slot_found) == 0)
-		goto err;
-
-	/*
-	 * The library we use, set in def_PK11_LIBNAME, may not offer any
-	 * slot(s). In that case, we must not proceed but we must not return an
-	 * error. The reason is that applications that try to set up the PKCS#11
-	 * engine don't exit on error during the engine initialization just
-	 * because no slot was present.
-	 */
-	if (any_slot_found == 0)
-		return (1);
-
-	if (global_session == CK_INVALID_HANDLE)
-		{
-		/* Open the global_session for the new process */
-		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
-			NULL_PTR, NULL_PTR, &global_session);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_LIBRARY_INIT,
-			    PK11_R_OPENSESSION, rv);
-			goto err;
-			}
-		}
-
-	/*
-	 * Disable digest if C_GetOperationState is not supported since
-	 * this function is required by OpenSSL digest copy function
-	 */
-	if (pFuncList->C_GetOperationState(global_session, NULL, &ul_state_len)
-			== CKR_FUNCTION_NOT_SUPPORTED) {
-		DEBUG_SLOT_SEL("%s: C_GetOperationState() not supported, "
-		    "setting digest_count to 0\n", PK11_DBG);
-		digest_count = 0;
-	}
-
-	pk11_library_initialized = CK_TRUE;
-	pk11_pid = getpid();
-	/*
-	 * if initialization of the locks fails pk11_init_all_locks()
-	 * will do the cleanup.
-	 */
-	if (!pk11_init_all_locks())
-		goto err;
-	for (i = 0; i < OP_MAX; i++)
-		session_cache[i].head = NULL;
-	/*
-	 * initialize active lists. We only use active lists
-	 * for asymmetric ciphers.
-	 */
-	for (i = 0; i < OP_MAX; i++)
-		active_list[i] = NULL;
-
-	if (!pk11_atfork_initialized)
-		{
-		if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
-		    pk11_fork_child) != 0)
-			{
-			PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
-			goto err;
-			}
-		pk11_atfork_initialized = CK_TRUE;
-		}
-
-	return (1);
-
-err:
-	return (0);
-	}
-
-/* Destructor (complements the "ENGINE_pk11()" constructor) */
-/* ARGSUSED */
-static int pk11_destroy(ENGINE *e)
-	{
-	free_PK11_LIBNAME();
-	ERR_unload_pk11_strings();
-	return (1);
-	}
-
-/*
- * Termination function to clean up the session, the token, and the pk11
- * library.
- */
-/* ARGSUSED */
-static int pk11_finish(ENGINE *e)
-	{
-	int i;
-
-	if (pk11_dso == NULL)
-		{
-		PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
-		goto err;
-		}
-
-	OPENSSL_assert(pFuncList != NULL);
-
-	if (pk11_free_all_sessions() == 0)
-		goto err;
-
-	/* free all active lists */
-	for (i = 0; i < OP_MAX; i++)
-		pk11_free_active_list(i);
-
-	pFuncList->C_CloseSession(global_session);
-	global_session = CK_INVALID_HANDLE;
-
-	/*
-	 * Since we are part of a library (libcrypto.so), calling this function
-	 * may have side-effects.
-	 */
-#if 0
-	pFuncList->C_Finalize(NULL);
-#endif
-#ifdef	SOLARIS_AES_CTR
-	{
-		ASN1_OBJECT *ob = NULL;
-		if (NID_aes_128_ctr != NID_undef) {
-			ob = OBJ_nid2obj(NID_aes_128_ctr);
-			if (ob != NULL)
-				ASN1_OBJECT_free(ob);
-		}
-		if (NID_aes_192_ctr != NID_undef) {
-			ob = OBJ_nid2obj(NID_aes_192_ctr);
-			if (ob != NULL)
-				ASN1_OBJECT_free(ob);
-		}
-		if (NID_aes_256_ctr != NID_undef) {
-			ob = OBJ_nid2obj(NID_aes_256_ctr);
-			if (ob != NULL)
-				ASN1_OBJECT_free(ob);
-		}
-	}
-#endif
-
-	if (!DSO_free(pk11_dso))
-		{
-		PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-	pk11_dso = NULL;
-	pFuncList = NULL;
-	pk11_library_initialized = CK_FALSE;
-	pk11_pid = 0;
-	/*
-	 * There is no way how to unregister atfork handlers (other than
-	 * unloading the library) so we just free the locks. For this reason
-	 * the atfork handlers check if the engine is initialized and bail out
-	 * immediately if not. This is necessary in case a process finishes
-	 * the engine before calling fork().
-	 */
-	pk11_free_all_locks();
-
-	return (1);
-
-err:
-	return (0);
-	}
-
-/* Standard engine interface function to set the dynamic library path */
-/* ARGSUSED */
-static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
-	{
-	int initialized = ((pk11_dso == NULL) ? 0 : 1);
-
-	switch (cmd)
-		{
-	case PK11_CMD_SO_PATH:
-		if (p == NULL)
-			{
-			PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
-			return (0);
-			}
-
-		if (initialized)
-			{
-			PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
-			return (0);
-			}
-
-		return (set_PK11_LIBNAME((const char *)p));
-	default:
-		break;
-		}
-
-	PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
-
-	return (0);
-	}
-
-
-/* Required function by the engine random interface. It does nothing here */
-static void pk11_rand_cleanup(void)
-	{
-	return;
-	}
-
-/* ARGSUSED */
-static void pk11_rand_add(const void *buf, int num, double add)
-	{
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RAND)) == NULL)
-		return;
-
-	/*
-	 * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
-	 * the calling functions do not care anyway
-	 */
-	pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
-	pk11_return_session(sp, OP_RAND);
-
-	return;
-	}
-
-static void pk11_rand_seed(const void *buf, int num)
-	{
-	pk11_rand_add(buf, num, 0);
-	}
-
-static int pk11_rand_bytes(unsigned char *buf, int num)
-	{
-	CK_RV rv;
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RAND)) == NULL)
-		return (0);
-
-	rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
-		pk11_return_session(sp, OP_RAND);
-		return (0);
-		}
-
-	pk11_return_session(sp, OP_RAND);
-	return (1);
-	}
-
-/* Required function by the engine random interface. It does nothing here */
-static int pk11_rand_status(void)
-	{
-	return (1);
-	}
-
-/* Free all BIGNUM structures from PK11_SESSION. */
-static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
-	{
-	switch (optype)
-		{
-#ifndef	OPENSSL_NO_RSA
-		case OP_RSA:
-			if (sp->opdata_rsa_n_num != NULL)
-				{
-				BN_free(sp->opdata_rsa_n_num);
-				sp->opdata_rsa_n_num = NULL;
-				}
-			if (sp->opdata_rsa_e_num != NULL)
-				{
-				BN_free(sp->opdata_rsa_e_num);
-				sp->opdata_rsa_e_num = NULL;
-				}
-			if (sp->opdata_rsa_d_num != NULL)
-				{
-				BN_free(sp->opdata_rsa_d_num);
-				sp->opdata_rsa_d_num = NULL;
-				}
-			break;
-#endif
-#ifndef	OPENSSL_NO_DSA
-		case OP_DSA:
-			if (sp->opdata_dsa_pub_num != NULL)
-				{
-				BN_free(sp->opdata_dsa_pub_num);
-				sp->opdata_dsa_pub_num = NULL;
-				}
-			if (sp->opdata_dsa_priv_num != NULL)
-				{
-				BN_free(sp->opdata_dsa_priv_num);
-				sp->opdata_dsa_priv_num = NULL;
-				}
-			break;
-#endif
-#ifndef	OPENSSL_NO_DH
-		case OP_DH:
-			if (sp->opdata_dh_priv_num != NULL)
-				{
-				BN_free(sp->opdata_dh_priv_num);
-				sp->opdata_dh_priv_num = NULL;
-				}
-			break;
-#endif
-		default:
-			break;
-		}
-	}
-
-/*
- * Get new PK11_SESSION structure ready for use. Every process must have
- * its own freelist of PK11_SESSION structures so handle fork() here
- * by destroying the old and creating new freelist.
- * The returned PK11_SESSION structure is disconnected from the freelist.
- */
-PK11_SESSION *
-pk11_get_session(PK11_OPTYPE optype)
-	{
-	PK11_SESSION *sp = NULL, *sp1, *freelist;
-	pthread_mutex_t *freelist_lock;
-	static pid_t pid = 0;
-	pid_t new_pid;
-	CK_RV rv;
-
-	switch (optype)
-		{
-		case OP_RSA:
-		case OP_DSA:
-		case OP_DH:
-		case OP_RAND:
-		case OP_DIGEST:
-		case OP_CIPHER:
-			freelist_lock = session_cache[optype].lock;
-			break;
-		default:
-			PK11err(PK11_F_GET_SESSION,
-				PK11_R_INVALID_OPERATION_TYPE);
-			return (NULL);
-		}
-	(void) pthread_mutex_lock(freelist_lock);
-
-	/*
-	 * Will use it to find out if we forked. We cannot use the PID field in
-	 * the session structure because we could get a newly allocated session
-	 * here, with no PID information.
-	 */
-	if (pid == 0)
-		pid = getpid();
-
-	freelist = session_cache[optype].head;
-	sp = freelist;
-
-	/*
-	 * If the free list is empty, allocate new uninitialized (filled
-	 * with zeroes) PK11_SESSION structure otherwise return first
-	 * structure from the freelist.
-	 */
-	if (sp == NULL)
-		{
-		if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
-			{
-			PK11err(PK11_F_GET_SESSION,
-				PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		(void) memset(sp, 0, sizeof (PK11_SESSION));
-
-		/*
-		 * It is a new session so it will look like a cache miss to the
-		 * code below. So, we must not try to to destroy its members so
-		 * mark them as unused.
-		 */
-		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
-		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
-		}
-	else
-		freelist = sp->next;
-
-	/*
-	 * Check whether we have forked. In that case, we must get rid of all
-	 * inherited sessions and start allocating new ones.
-	 */
-	if (pid != (new_pid = getpid()))
-		{
-		pid = new_pid;
-
-		/*
-		 * We are a new process and thus need to free any inherited
-		 * PK11_SESSION objects aside from the first session (sp) which
-		 * is the only PK11_SESSION structure we will reuse (for the
-		 * head of the list).
-		 */
-		while ((sp1 = freelist) != NULL)
-			{
-			freelist = sp1->next;
-			/*
-			 * NOTE: we do not want to call pk11_free_all_sessions()
-			 * here because it would close underlying PKCS#11
-			 * sessions and destroy all objects.
-			 */
-			pk11_free_nums(sp1, optype);
-			OPENSSL_free(sp1);
-			}
-
-		/* we have to free the active list as well. */
-		pk11_free_active_list(optype);
-
-		/* Initialize the process */
-		rv = pFuncList->C_Initialize(NULL_PTR);
-		if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
-			{
-			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
-			    rv);
-			OPENSSL_free(sp);
-			sp = NULL;
-			goto err;
-			}
-
-		/*
-		 * Choose slot here since the slot table is different on this
-		 * process. If we are here then we must have found at least one
-		 * usable slot before so we don't need to check any_slot_found.
-		 * See pk11_library_init()'s usage of this function for more
-		 * information.
-		 */
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-		if (check_hw_mechanisms() == 0)
-			goto err;
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-		if (pk11_choose_slots(NULL) == 0)
-			goto err;
-
-		/* Open the global_session for the new process */
-		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
-			NULL_PTR, NULL_PTR, &global_session);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
-			    rv);
-			OPENSSL_free(sp);
-			sp = NULL;
-			goto err;
-			}
-
-		/*
-		 * It is an inherited session from our parent so it needs
-		 * re-initialization.
-		 */
-		if (pk11_setup_session(sp, optype) == 0)
-			{
-			OPENSSL_free(sp);
-			sp = NULL;
-			goto err;
-			}
-		if (pk11_token_relogin(sp->session) == 0)
-			{
-			/*
-			 * We will keep the session in the cache list and let
-			 * the caller cope with the situation.
-			 */
-			freelist = sp;
-			sp = NULL;
-			goto err;
-			}
-		}
-
-	if (sp->pid == 0)
-		{
-		/* It is a new session and needs initialization. */
-		if (pk11_setup_session(sp, optype) == 0)
-			{
-			OPENSSL_free(sp);
-			sp = NULL;
-			}
-		}
-
-	/* set new head for the list of PK11_SESSION objects */
-	session_cache[optype].head = freelist;
-
-err:
-	if (sp != NULL)
-		sp->next = NULL;
-
-	(void) pthread_mutex_unlock(freelist_lock);
-
-	return (sp);
-	}
-
-
-void
-pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
-	{
-	pthread_mutex_t *freelist_lock;
-	PK11_SESSION *freelist;
-
-	/*
-	 * If this is a session from the parent it will be taken care of and
-	 * freed in pk11_get_session() as part of the post-fork clean up the
-	 * next time we will ask for a new session.
-	 */
-	if (sp == NULL || sp->pid != getpid())
-		return;
-
-	switch (optype)
-		{
-		case OP_RSA:
-		case OP_DSA:
-		case OP_DH:
-		case OP_RAND:
-		case OP_DIGEST:
-		case OP_CIPHER:
-			freelist_lock = session_cache[optype].lock;
-			break;
-		default:
-			PK11err(PK11_F_RETURN_SESSION,
-				PK11_R_INVALID_OPERATION_TYPE);
-			return;
-		}
-
-	(void) pthread_mutex_lock(freelist_lock);
-	freelist = session_cache[optype].head;
-	sp->next = freelist;
-	session_cache[optype].head = sp;
-	(void) pthread_mutex_unlock(freelist_lock);
-	}
-
-
-/* Destroy all objects. This function is called when the engine is finished */
-static int pk11_free_all_sessions()
-	{
-	int ret = 1;
-	int type;
-
-#ifndef OPENSSL_NO_RSA
-	(void) pk11_destroy_rsa_key_objects(NULL);
-#endif	/* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-	(void) pk11_destroy_dsa_key_objects(NULL);
-#endif	/* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-	(void) pk11_destroy_dh_key_objects(NULL);
-#endif	/* OPENSSL_NO_DH */
-	(void) pk11_destroy_cipher_key_objects(NULL);
-
-	/*
-	 * We try to release as much as we can but any error means that we will
-	 * return 0 on exit.
-	 */
-	for (type = 0; type < OP_MAX; type++)
-		{
-		if (pk11_free_session_list(type) == 0)
-			ret = 0;
-		}
-
-	return (ret);
-	}
-
-/*
- * Destroy session structures from the linked list specified. Free as many
- * sessions as possible but any failure in C_CloseSession() means that we
- * return an error on return.
- */
-static int pk11_free_session_list(PK11_OPTYPE optype)
-	{
-	CK_RV rv;
-	PK11_SESSION *sp = NULL;
-	PK11_SESSION *freelist = NULL;
-	pid_t mypid = getpid();
-	pthread_mutex_t *freelist_lock;
-	int ret = 1;
-
-	switch (optype)
-		{
-		case OP_RSA:
-		case OP_DSA:
-		case OP_DH:
-		case OP_RAND:
-		case OP_DIGEST:
-		case OP_CIPHER:
-			freelist_lock = session_cache[optype].lock;
-			break;
-		default:
-			PK11err(PK11_F_FREE_ALL_SESSIONS,
-				PK11_R_INVALID_OPERATION_TYPE);
-			return (0);
-		}
-
-	(void) pthread_mutex_lock(freelist_lock);
-	freelist = session_cache[optype].head;
-	while ((sp = freelist) != NULL)
-		{
-		if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
-			{
-			rv = pFuncList->C_CloseSession(sp->session);
-			if (rv != CKR_OK)
-				{
-				PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
-					PK11_R_CLOSESESSION, rv);
-				ret = 0;
-				}
-			}
-		freelist = sp->next;
-		pk11_free_nums(sp, optype);
-		OPENSSL_free(sp);
-		}
-
-	(void) pthread_mutex_unlock(freelist_lock);
-	return (ret);
-	}
-
-
-static int
-pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
-	{
-	CK_RV rv;
-	CK_SLOT_ID myslot;
-
-	switch (optype)
-		{
-		case OP_RSA:
-		case OP_DSA:
-		case OP_DH:
-			myslot = pubkey_SLOTID;
-			break;
-		case OP_RAND:
-			myslot = rand_SLOTID;
-			break;
-		case OP_DIGEST:
-		case OP_CIPHER:
-			myslot = SLOTID;
-			break;
-		default:
-			PK11err(PK11_F_SETUP_SESSION,
-			    PK11_R_INVALID_OPERATION_TYPE);
-			return (0);
-		}
-
-	sp->session = CK_INVALID_HANDLE;
-	DEBUG_SLOT_SEL("%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
-	rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
-		NULL_PTR, NULL_PTR, &sp->session);
-	if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
-		{
-		/*
-		 * We are probably a child process so force the
-		 * reinitialize of the session
-		 */
-		pk11_library_initialized = CK_FALSE;
-		if (!pk11_library_init(NULL))
-			return (0);
-		rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
-			NULL_PTR, NULL_PTR, &sp->session);
-		}
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
-		return (0);
-		}
-
-	sp->pid = getpid();
-
-	switch (optype)
-		{
-#ifndef OPENSSL_NO_RSA
-		case OP_RSA:
-			sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
-			sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
-			sp->opdata_rsa_pub = NULL;
-			sp->opdata_rsa_n_num = NULL;
-			sp->opdata_rsa_e_num = NULL;
-			sp->opdata_rsa_priv = NULL;
-			sp->opdata_rsa_d_num = NULL;
-			break;
-#endif	/* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-		case OP_DSA:
-			sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
-			sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
-			sp->opdata_dsa_pub = NULL;
-			sp->opdata_dsa_pub_num = NULL;
-			sp->opdata_dsa_priv = NULL;
-			sp->opdata_dsa_priv_num = NULL;
-			break;
-#endif	/* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-		case OP_DH:
-			sp->opdata_dh_key = CK_INVALID_HANDLE;
-			sp->opdata_dh = NULL;
-			sp->opdata_dh_priv_num = NULL;
-			break;
-#endif	/* OPENSSL_NO_DH */
-		case OP_CIPHER:
-			sp->opdata_cipher_key = CK_INVALID_HANDLE;
-			sp->opdata_encrypt = -1;
-			break;
-		}
-
-	/*
-	 * We always initialize the session as containing a non-persistent
-	 * object. The key load functions set it to persistent if that is so.
-	 */
-	sp->persistent = CK_FALSE;
-	return (1);
-	}
-
-#ifndef OPENSSL_NO_RSA
-/*
- * Destroy all non-NULL RSA parameters. For the RSA keys by reference code,
- * public components 'n'/'e' are the key components we use to check for the
- * cache hit even for the private keys. So, no matter whether we are destroying
- * a public or a private key, we always free what we can.
- */
-static void
-destroy_all_rsa_params(PK11_SESSION *sp)
-	{
-	if (sp->opdata_rsa_n_num != NULL)
-		{
-		BN_free(sp->opdata_rsa_n_num);
-		sp->opdata_rsa_n_num = NULL;
-		}
-	if (sp->opdata_rsa_e_num != NULL)
-		{
-		BN_free(sp->opdata_rsa_e_num);
-		sp->opdata_rsa_e_num = NULL;
-		}
-	if (sp->opdata_rsa_d_num != NULL)
-		{
-		BN_free(sp->opdata_rsa_d_num);
-		sp->opdata_rsa_d_num = NULL;
-		}
-	}
-
-/* Destroy RSA public key from single session. */
-int
-pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
-	{
-	int ret = 0;
-
-	if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
-		{
-		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_pub_key,
-		    ret, uselock, OP_RSA);
-		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
-		sp->opdata_rsa_pub = NULL;
-		destroy_all_rsa_params(sp);
-		}
-
-	return (ret);
-	}
-
-/* Destroy RSA private key from single session. */
-int
-pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
-	{
-	int ret = 0;
-
-	if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
-		{
-		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_priv_key,
-		    ret, uselock, OP_RSA);
-		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
-		sp->opdata_rsa_priv = NULL;
-		destroy_all_rsa_params(sp);
-		}
-
-	return (ret);
-	}
-
-/*
- * Destroy RSA key object wrapper. If session is NULL, try to destroy all
- * objects in the free list.
- */
-int
-pk11_destroy_rsa_key_objects(PK11_SESSION *session)
-	{
-	int ret = 1;
-	PK11_SESSION *sp = NULL;
-	PK11_SESSION *local_free_session;
-	CK_BBOOL uselock = CK_TRUE;
-
-	if (session != NULL)
-		local_free_session = session;
-	else
-		{
-		(void) pthread_mutex_lock(session_cache[OP_RSA].lock);
-		local_free_session = session_cache[OP_RSA].head;
-		uselock = CK_FALSE;
-		}
-
-	/*
-	 * go through the list of sessions and delete key objects
-	 */
-	while ((sp = local_free_session) != NULL)
-		{
-		local_free_session = sp->next;
-
-		/*
-		 * Do not terminate list traversal if one of the
-		 * destroy operations fails.
-		 */
-		if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
-			{
-			ret = 0;
-			continue;
-			}
-		if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
-			{
-			ret = 0;
-			continue;
-			}
-		}
-
-	if (session == NULL)
-		(void) pthread_mutex_unlock(session_cache[OP_RSA].lock);
-
-	return (ret);
-	}
-#endif	/* OPENSSL_NO_RSA */
-
-#ifndef OPENSSL_NO_DSA
-/* Destroy DSA public key from single session. */
-int
-pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
-	{
-	int ret = 0;
-
-	if (sp->opdata_dsa_pub_key != CK_INVALID_HANDLE)
-		{
-		TRY_OBJ_DESTROY(sp, sp->opdata_dsa_pub_key,
-		    ret, uselock, OP_DSA);
-		sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
-		sp->opdata_dsa_pub = NULL;
-		if (sp->opdata_dsa_pub_num != NULL)
-			{
-			BN_free(sp->opdata_dsa_pub_num);
-			sp->opdata_dsa_pub_num = NULL;
-			}
-		}
-
-	return (ret);
-	}
-
-/* Destroy DSA private key from single session. */
-int
-pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
-	{
-	int ret = 0;
-
-	if (sp->opdata_dsa_priv_key != CK_INVALID_HANDLE)
-		{
-		TRY_OBJ_DESTROY(sp, sp->opdata_dsa_priv_key,
-		    ret, uselock, OP_DSA);
-		sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
-		sp->opdata_dsa_priv = NULL;
-		if (sp->opdata_dsa_priv_num != NULL)
-			{
-			BN_free(sp->opdata_dsa_priv_num);
-			sp->opdata_dsa_priv_num = NULL;
-			}
-		}
-
-	return (ret);
-	}
-
-/*
- * Destroy DSA key object wrapper. If session is NULL, try to destroy all
- * objects in the free list.
- */
-int
-pk11_destroy_dsa_key_objects(PK11_SESSION *session)
-	{
-	int ret = 1;
-	PK11_SESSION *sp = NULL;
-	PK11_SESSION *local_free_session;
-	CK_BBOOL uselock = CK_TRUE;
-
-	if (session != NULL)
-		local_free_session = session;
-	else
-		{
-		(void) pthread_mutex_lock(session_cache[OP_DSA].lock);
-		local_free_session = session_cache[OP_DSA].head;
-		uselock = CK_FALSE;
-		}
-
-	/*
-	 * go through the list of sessions and delete key objects
-	 */
-	while ((sp = local_free_session) != NULL)
-		{
-		local_free_session = sp->next;
-
-		/*
-		 * Do not terminate list traversal if one of the
-		 * destroy operations fails.
-		 */
-		if (pk11_destroy_dsa_object_pub(sp, uselock) == 0)
-			{
-			ret = 0;
-			continue;
-			}
-		if (pk11_destroy_dsa_object_priv(sp, uselock) == 0)
-			{
-			ret = 0;
-			continue;
-			}
-		}
-
-	if (session == NULL)
-		(void) pthread_mutex_unlock(session_cache[OP_DSA].lock);
-
-	return (ret);
-	}
-#endif	/* OPENSSL_NO_DSA */
-
-#ifndef OPENSSL_NO_DH
-/* Destroy DH key from single session. */
-int
-pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock)
-	{
-	int ret = 0;
-
-	if (sp->opdata_dh_key != CK_INVALID_HANDLE)
-		{
-		TRY_OBJ_DESTROY(sp, sp->opdata_dh_key,
-		    ret, uselock, OP_DH);
-		sp->opdata_dh_key = CK_INVALID_HANDLE;
-		sp->opdata_dh = NULL;
-		if (sp->opdata_dh_priv_num != NULL)
-			{
-			BN_free(sp->opdata_dh_priv_num);
-			sp->opdata_dh_priv_num = NULL;
-			}
-		}
-
-	return (ret);
-	}
-
-/*
- * Destroy DH key object wrapper.
- *
- * arg0: pointer to PKCS#11 engine session structure
- *       if session is NULL, try to destroy all objects in the free list
- */
-int
-pk11_destroy_dh_key_objects(PK11_SESSION *session)
-	{
-	int ret = 1;
-	PK11_SESSION *sp = NULL;
-	PK11_SESSION *local_free_session;
-	CK_BBOOL uselock = CK_TRUE;
-
-	if (session != NULL)
-		local_free_session = session;
-	else
-		{
-		(void) pthread_mutex_lock(session_cache[OP_DH].lock);
-		local_free_session = session_cache[OP_DH].head;
-		uselock = CK_FALSE;
-		}
-
-	while ((sp = local_free_session) != NULL)
-		{
-		local_free_session = sp->next;
-
-		/*
-		 * Do not terminate list traversal if one of the
-		 * destroy operations fails.
-		 */
-		if (pk11_destroy_dh_object(sp, uselock) == 0)
-			{
-			ret = 0;
-			continue;
-			}
-		}
-err:
-	if (session == NULL)
-		(void) pthread_mutex_unlock(session_cache[OP_DH].lock);
-
-	return (ret);
-	}
-#endif	/* OPENSSL_NO_DH */
-
-static int
-pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
-    CK_BBOOL persistent)
-	{
-	CK_RV rv;
-
-	/*
-	 * We never try to destroy persistent objects which are the objects
-	 * stored in the keystore. Also, we always use read-only sessions so
-	 * C_DestroyObject() would be returning CKR_SESSION_READ_ONLY here.
-	 */
-	if (persistent == CK_TRUE)
-		return (1);
-
-	rv = pFuncList->C_DestroyObject(session, oh);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
-		    rv);
-		return (0);
-		}
-
-	return (1);
-	}
-
-
-/* Symmetric ciphers and digests support functions */
-
-static int
-cipher_nid_to_pk11(int nid)
-	{
-	int i;
-
-	for (i = 0; i < PK11_CIPHER_MAX; i++)
-		if (ciphers[i].nid == nid)
-			return (ciphers[i].id);
-	return (-1);
-	}
-
-static int
-pk11_usable_ciphers(const int **nids)
-	{
-	if (cipher_count > 0)
-		*nids = cipher_nids;
-	else
-		*nids = NULL;
-	return (cipher_count);
-	}
-
-static int
-pk11_usable_digests(const int **nids)
-	{
-	if (digest_count > 0)
-		*nids = digest_nids;
-	else
-		*nids = NULL;
-	return (digest_count);
-	}
-
-/*
- * Init context for encryption or decryption using a symmetric key.
- */
-static int pk11_init_symmetric(EVP_CIPHER_CTX *ctx, PK11_CIPHER *pcipher,
-	PK11_SESSION *sp, CK_MECHANISM_PTR pmech)
-	{
-	CK_RV rv;
-#ifdef	SOLARIS_AES_CTR
-	CK_AES_CTR_PARAMS ctr_params;
-#endif	/* SOLARIS_AES_CTR */
-
-	/*
-	 * We expect pmech->mechanism to be already set and
-	 * pParameter/ulParameterLen initialized to NULL/0 before
-	 * pk11_init_symmetric() is called.
-	 */
-	OPENSSL_assert(pmech->mechanism != NULL);
-	OPENSSL_assert(pmech->pParameter == NULL);
-	OPENSSL_assert(pmech->ulParameterLen == 0);
-
-#ifdef	SOLARIS_AES_CTR
-	if (ctx->cipher->nid == NID_aes_128_ctr ||
-	    ctx->cipher->nid == NID_aes_192_ctr ||
-	    ctx->cipher->nid == NID_aes_256_ctr)
-		{
-		pmech->pParameter = (void *)(&ctr_params);
-		pmech->ulParameterLen = sizeof (ctr_params);
-		/*
-		 * For now, we are limited to the fixed length of the counter,
-		 * it covers the whole counter block. That's what RFC 4344
-		 * needs. For more information on internal structure of the
-		 * counter block, see RFC 3686. If needed in the future, we can
-		 * add code so that the counter length can be set via
-		 * ENGINE_ctrl() function.
-		 */
-		ctr_params.ulCounterBits = AES_BLOCK_SIZE * 8;
-		OPENSSL_assert(pcipher->iv_len == AES_BLOCK_SIZE);
-		(void) memcpy(ctr_params.cb, ctx->iv, AES_BLOCK_SIZE);
-		}
-	else
-#endif	/* SOLARIS_AES_CTR */
-		{
-		if (pcipher->iv_len > 0)
-			{
-			pmech->pParameter = (void *)ctx->iv;
-			pmech->ulParameterLen = pcipher->iv_len;
-			}
-		}
-
-	/* if we get here, the encryption needs to be reinitialized */
-	if (ctx->encrypt)
-		rv = pFuncList->C_EncryptInit(sp->session, pmech,
-			sp->opdata_cipher_key);
-	else
-		rv = pFuncList->C_DecryptInit(sp->session, pmech,
-			sp->opdata_cipher_key);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_CIPHER_INIT, ctx->encrypt ?
-		    PK11_R_ENCRYPTINIT : PK11_R_DECRYPTINIT, rv);
-		pk11_return_session(sp, OP_CIPHER);
-		return (0);
-		}
-
-	return (1);
-	}
-
-/* ARGSUSED */
-static int
-pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-    const unsigned char *iv, int enc)
-	{
-	CK_MECHANISM mech;
-	int index;
-	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
-	PK11_SESSION *sp;
-	PK11_CIPHER *p_ciph_table_row;
-
-	state->sp = NULL;
-
-	index = cipher_nid_to_pk11(ctx->cipher->nid);
-	if (index < 0 || index >= PK11_CIPHER_MAX)
-		return (0);
-
-	p_ciph_table_row = &ciphers[index];
-	/*
-	 * iv_len in the ctx->cipher structure is the maximum IV length for the
-	 * current cipher and it must be less or equal to the IV length in our
-	 * ciphers table. The key length must be in the allowed interval. From
-	 * all cipher modes that the PKCS#11 engine supports only RC4 allows a
-	 * key length to be in some range, all other NIDs have a precise key
-	 * length. Every application can define its own EVP functions so this
-	 * code serves as a sanity check.
-	 *
-	 * Note that the reason why the IV length in ctx->cipher might be
-	 * greater than the actual length is that OpenSSL uses BLOCK_CIPHER_defs
-	 * macro to define functions that return EVP structures for all DES
-	 * modes. So, even ECB modes get 8 byte IV.
-	 */
-	if (ctx->cipher->iv_len < p_ciph_table_row->iv_len ||
-	    ctx->key_len < p_ciph_table_row->min_key_len ||
-	    ctx->key_len > p_ciph_table_row->max_key_len) {
-		PK11err(PK11_F_CIPHER_INIT, PK11_R_KEY_OR_IV_LEN_PROBLEM);
-		return (0);
-	}
-
-	if ((sp = pk11_get_session(OP_CIPHER)) == NULL)
-		return (0);
-
-	/* if applicable, the mechanism parameter is used for IV */
-	mech.mechanism = p_ciph_table_row->mech_type;
-	mech.pParameter = NULL;
-	mech.ulParameterLen = 0;
-
-	/* The key object is destroyed here if it is not the current key. */
-	(void) check_new_cipher_key(sp, key, ctx->key_len);
-
-	/*
-	 * If the key is the same and the encryption is also the same, then
-	 * just reuse it. However, we must not forget to reinitialize the
-	 * context that was finalized in pk11_cipher_cleanup().
-	 */
-	if (sp->opdata_cipher_key != CK_INVALID_HANDLE &&
-	    sp->opdata_encrypt == ctx->encrypt)
-		{
-		state->sp = sp;
-		if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
-			return (0);
-
-		return (1);
-		}
-
-	/*
-	 * Check if the key has been invalidated. If so, a new key object
-	 * needs to be created.
-	 */
-	if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
-		{
-		sp->opdata_cipher_key = pk11_get_cipher_key(
-			ctx, key, p_ciph_table_row->key_type, sp);
-		}
-
-	if (sp->opdata_encrypt != ctx->encrypt && sp->opdata_encrypt != -1)
-		{
-		/*
-		 * The previous encryption/decryption is different. Need to
-		 * terminate the previous * active encryption/decryption here.
-		 */
-		if (!pk11_cipher_final(sp))
-			{
-			pk11_return_session(sp, OP_CIPHER);
-			return (0);
-			}
-		}
-
-	if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
-		{
-		pk11_return_session(sp, OP_CIPHER);
-		return (0);
-		}
-
-	/* now initialize the context with a new key */
-	if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
-		return (0);
-
-	sp->opdata_encrypt = ctx->encrypt;
-	state->sp = sp;
-
-	return (1);
-	}
-
-/*
- * When reusing the same key in an encryption/decryption session for a
- * decryption/encryption session, we need to close the active session
- * and recreate a new one. Note that the key is in the global session so
- * that it needs not be recreated.
- *
- * It is more appropriate to use C_En/DecryptFinish here. At the time of this
- * development, these two functions in the PKCS#11 libraries used return
- * unexpected errors when passing in 0 length output. It may be a good
- * idea to try them again if performance is a problem here and fix
- * C_En/DecryptFinial if there are bugs there causing the problem.
- */
-static int
-pk11_cipher_final(PK11_SESSION *sp)
-	{
-	CK_RV rv;
-
-	rv = pFuncList->C_CloseSession(sp->session);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_CLOSESESSION, rv);
-		return (0);
-		}
-
-	rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
-		NULL_PTR, NULL_PTR, &sp->session);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_OPENSESSION, rv);
-		return (0);
-		}
-
-	return (1);
-	}
-
-/*
- * An engine interface function. The calling function allocates sufficient
- * memory for the output buffer "out" to hold the results.
- */
-static int
-pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-	const unsigned char *in, unsigned int inl)
-	{
-	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
-	PK11_SESSION *sp;
-	CK_RV rv;
-	unsigned long outl = inl;
-
-	if (state == NULL || state->sp == NULL)
-		return (0);
-
-	sp = (PK11_SESSION *) state->sp;
-
-	if (!inl)
-		return (1);
-
-	/* RC4 is the only stream cipher we support */
-	if (ctx->cipher->nid != NID_rc4 && (inl % ctx->cipher->block_size) != 0)
-		return (0);
-
-	if (ctx->encrypt)
-		{
-		rv = pFuncList->C_EncryptUpdate(sp->session,
-			(unsigned char *)in, inl, out, &outl);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
-			    PK11_R_ENCRYPTUPDATE, rv);
-			return (0);
-			}
-		}
-	else
-		{
-		rv = pFuncList->C_DecryptUpdate(sp->session,
-			(unsigned char *)in, inl, out, &outl);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
-			    PK11_R_DECRYPTUPDATE, rv);
-			return (0);
-			}
-		}
-
-	/*
-	 * For DES_CBC, DES3_CBC, AES_CBC, and RC4, the output size is always
-	 * the same size of input.
-	 * The application has guaranteed to call the block ciphers with
-	 * correctly aligned buffers.
-	 */
-	if (inl != outl)
-		return (0);
-
-	return (1);
-	}
-
-/*
- * Return the session to the pool. Calling C_EncryptFinal() and C_DecryptFinal()
- * here is the right thing because in EVP_DecryptFinal_ex(), engine's
- * do_cipher() is not even called, and in EVP_EncryptFinal_ex() it is called but
- * the engine can't find out that it's the finalizing call. We wouldn't
- * necessarily have to finalize the context here since reinitializing it with
- * C_(Encrypt|Decrypt)Init() should be fine but for the sake of correctness,
- * let's do it. Some implementations might leak memory if the previously used
- * context is initialized without finalizing it first.
- */
-static int
-pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx)
-	{
-	CK_RV rv;
-	CK_ULONG len = EVP_MAX_BLOCK_LENGTH;
-	CK_BYTE buf[EVP_MAX_BLOCK_LENGTH];
-	PK11_CIPHER_STATE *state = ctx->cipher_data;
-
-	if (state != NULL && state->sp != NULL)
-		{
-		/*
-		 * We are not interested in the data here, we just need to get
-		 * rid of the context.
-		 */
-		if (ctx->encrypt)
-			rv = pFuncList->C_EncryptFinal(
-			    state->sp->session, buf, &len);
-		else
-			rv = pFuncList->C_DecryptFinal(
-			    state->sp->session, buf, &len);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_CIPHER_CLEANUP, ctx->encrypt ?
-			    PK11_R_ENCRYPTFINAL : PK11_R_DECRYPTFINAL, rv);
-			pk11_return_session(state->sp, OP_CIPHER);
-			return (0);
-			}
-
-		pk11_return_session(state->sp, OP_CIPHER);
-		state->sp = NULL;
-		}
-
-	return (1);
-	}
-
-/*
- * Registered by the ENGINE when used to find out how to deal with
- * a particular NID in the ENGINE. This says what we'll do at the
- * top level - note, that list is restricted by what we answer with
- */
-/* ARGSUSED */
-static int
-pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-	const int **nids, int nid)
-	{
-	if (!cipher)
-		return (pk11_usable_ciphers(nids));
-
-	switch (nid)
-		{
-		case NID_des_ede3_cbc:
-			*cipher = &pk11_3des_cbc;
-			break;
-		case NID_des_cbc:
-			*cipher = &pk11_des_cbc;
-			break;
-		case NID_des_ede3_ecb:
-			*cipher = &pk11_3des_ecb;
-			break;
-		case NID_des_ecb:
-			*cipher = &pk11_des_ecb;
-			break;
-		case NID_aes_128_cbc:
-			*cipher = &pk11_aes_128_cbc;
-			break;
-		case NID_aes_192_cbc:
-			*cipher = &pk11_aes_192_cbc;
-			break;
-		case NID_aes_256_cbc:
-			*cipher = &pk11_aes_256_cbc;
-			break;
-		case NID_aes_128_ecb:
-			*cipher = &pk11_aes_128_ecb;
-			break;
-		case NID_aes_192_ecb:
-			*cipher = &pk11_aes_192_ecb;
-			break;
-		case NID_aes_256_ecb:
-			*cipher = &pk11_aes_256_ecb;
-			break;
-		case NID_bf_cbc:
-			*cipher = &pk11_bf_cbc;
-			break;
-		case NID_rc4:
-			*cipher = &pk11_rc4;
-			break;
-		default:
-#ifdef	SOLARIS_AES_CTR
-			/*
-			 * These can't be in separated cases because the NIDs
-			 * here are not constants.
-			 */
-			if (nid == NID_aes_128_ctr)
-				*cipher = &pk11_aes_128_ctr;
-			else if (nid == NID_aes_192_ctr)
-				*cipher = &pk11_aes_192_ctr;
-			else if (nid == NID_aes_256_ctr)
-				*cipher = &pk11_aes_256_ctr;
-			else
-#endif	/* SOLARIS_AES_CTR */
-			*cipher = NULL;
-			break;
-		}
-	return (*cipher != NULL);
-	}
-
-/* ARGSUSED */
-static int
-pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
-	const int **nids, int nid)
-	{
-	if (!digest)
-		return (pk11_usable_digests(nids));
-
-	switch (nid)
-		{
-		case NID_md5:
-			*digest = &pk11_md5;
-			break;
-		case NID_sha1:
-			*digest = &pk11_sha1;
-			break;
-		case NID_sha224:
-			*digest = &pk11_sha224;
-			break;
-		case NID_sha256:
-			*digest = &pk11_sha256;
-			break;
-		case NID_sha384:
-			*digest = &pk11_sha384;
-			break;
-		case NID_sha512:
-			*digest = &pk11_sha512;
-			break;
-		default:
-			*digest = NULL;
-			break;
-		}
-	return (*digest != NULL);
-	}
-
-
-/* Create a secret key object in a PKCS#11 session */
-static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
-	const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp)
-	{
-	CK_RV rv;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	CK_OBJECT_CLASS obj_key = CKO_SECRET_KEY;
-	CK_ULONG ul_key_attr_count = 6;
-
-	CK_ATTRIBUTE  a_key_template[] =
-		{
-		{CKA_CLASS, (void*) NULL, sizeof (CK_OBJECT_CLASS)},
-		{CKA_KEY_TYPE, (void*) NULL, sizeof (CK_KEY_TYPE)},
-		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
-		{CKA_ENCRYPT, &pk11_true, sizeof (pk11_true)},
-		{CKA_DECRYPT, &pk11_true, sizeof (pk11_true)},
-		{CKA_VALUE, (void*) NULL, 0},
-		};
-
-	/*
-	 * Create secret key object in global_session. All other sessions
-	 * can use the key handles. Here is why:
-	 * OpenSSL will call EncryptInit and EncryptUpdate using a secret key.
-	 * It may then call DecryptInit and DecryptUpdate using the same key.
-	 * To use the same key object, we need to call EncryptFinal with
-	 * a 0 length message. Currently, this does not work for 3DES
-	 * mechanism. To get around this problem, we close the session and
-	 * then create a new session to use the same key object. When a session
-	 * is closed, all the object handles will be invalid. Thus, create key
-	 * objects in a global session, an individual session may be closed to
-	 * terminate the active operation.
-	 */
-	CK_SESSION_HANDLE session = global_session;
-	a_key_template[0].pValue = &obj_key;
-	a_key_template[1].pValue = &key_type;
-	a_key_template[5].pValue = (void *) key;
-	a_key_template[5].ulValueLen = (unsigned long) ctx->key_len;
-
-	rv = pFuncList->C_CreateObject(session,
-		a_key_template, ul_key_attr_count, &h_key);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_CIPHER_KEY, PK11_R_CREATEOBJECT,
-		    rv);
-		goto err;
-		}
-
-	/*
-	 * Save the key information used in this session.
-	 * The max can be saved is PK11_KEY_LEN_MAX.
-	 */
-	sp->opdata_key_len = ctx->key_len > PK11_KEY_LEN_MAX ?
-		PK11_KEY_LEN_MAX : ctx->key_len;
-	(void) memcpy(sp->opdata_key, key, sp->opdata_key_len);
-err:
-
-	return (h_key);
-	}
-
-static int
-md_nid_to_pk11(int nid)
-	{
-	int i;
-
-	for (i = 0; i < PK11_DIGEST_MAX; i++)
-		if (digests[i].nid == nid)
-			return (digests[i].id);
-	return (-1);
-	}
-
-static int
-pk11_digest_init(EVP_MD_CTX *ctx)
-	{
-	CK_RV rv;
-	CK_MECHANISM mech;
-	int index;
-	PK11_SESSION *sp;
-	PK11_DIGEST *pdp;
-	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
-
-	state->sp = NULL;
-
-	index = md_nid_to_pk11(ctx->digest->type);
-	if (index < 0 || index >= PK11_DIGEST_MAX)
-		return (0);
-
-	pdp = &digests[index];
-	if ((sp = pk11_get_session(OP_DIGEST)) == NULL)
-		return (0);
-
-	/* at present, no parameter is needed for supported digests */
-	mech.mechanism = pdp->mech_type;
-	mech.pParameter = NULL;
-	mech.ulParameterLen = 0;
-
-	rv = pFuncList->C_DigestInit(sp->session, &mech);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_INIT, PK11_R_DIGESTINIT, rv);
-		pk11_return_session(sp, OP_DIGEST);
-		return (0);
-		}
-
-	state->sp = sp;
-
-	return (1);
-	}
-
-static int
-pk11_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
-	{
-	CK_RV rv;
-	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
-
-	/* 0 length message will cause a failure in C_DigestFinal */
-	if (count == 0)
-		return (1);
-
-	if (state == NULL || state->sp == NULL)
-		return (0);
-
-	rv = pFuncList->C_DigestUpdate(state->sp->session, (CK_BYTE *) data,
-		count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_UPDATE, PK11_R_DIGESTUPDATE, rv);
-		pk11_return_session(state->sp, OP_DIGEST);
-		state->sp = NULL;
-		return (0);
-		}
-
-	return (1);
-	}
-
-static int
-pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
-	{
-	CK_RV rv;
-	unsigned long len;
-	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
-	len = ctx->digest->md_size;
-
-	if (state == NULL || state->sp == NULL)
-		return (0);
-
-	rv = pFuncList->C_DigestFinal(state->sp->session, md, &len);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_FINAL, PK11_R_DIGESTFINAL, rv);
-		pk11_return_session(state->sp, OP_DIGEST);
-		state->sp = NULL;
-		return (0);
-		}
-
-	if (ctx->digest->md_size != len)
-		return (0);
-
-	/*
-	 * Final is called and digest is returned, so return the session
-	 * to the pool
-	 */
-	pk11_return_session(state->sp, OP_DIGEST);
-	state->sp = NULL;
-
-	return (1);
-	}
-
-static int
-pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
-	{
-	CK_RV rv;
-	int ret = 0;
-	PK11_CIPHER_STATE *state, *state_to;
-	CK_BYTE_PTR pstate = NULL;
-	CK_ULONG ul_state_len;
-
-	/* The copy-from state */
-	state = (PK11_CIPHER_STATE *) from->md_data;
-	if (state == NULL || state->sp == NULL)
-		goto err;
-
-	/* Initialize the copy-to state */
-	if (!pk11_digest_init(to))
-		goto err;
-	state_to = (PK11_CIPHER_STATE *) to->md_data;
-
-	/* Get the size of the operation state of the copy-from session */
-	rv = pFuncList->C_GetOperationState(state->sp->session, NULL,
-		&ul_state_len);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
-		    rv);
-		goto err;
-		}
-	if (ul_state_len == 0)
-		{
-		goto err;
-		}
-
-	pstate = OPENSSL_malloc(ul_state_len);
-	if (pstate == NULL)
-		{
-		PK11err(PK11_F_DIGEST_COPY, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	/* Get the operation state of the copy-from session */
-	rv = pFuncList->C_GetOperationState(state->sp->session, pstate,
-		&ul_state_len);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
-		    rv);
-		goto err;
-		}
-
-	/* Set the operation state of the copy-to session */
-	rv = pFuncList->C_SetOperationState(state_to->sp->session, pstate,
-		ul_state_len, 0, 0);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_COPY,
-		    PK11_R_SET_OPERATION_STATE, rv);
-		goto err;
-		}
-
-	ret = 1;
-err:
-	if (pstate != NULL)
-		OPENSSL_free(pstate);
-
-	return (ret);
-	}
-
-/* Return any pending session state to the pool */
-static int
-pk11_digest_cleanup(EVP_MD_CTX *ctx)
-	{
-	PK11_CIPHER_STATE *state = ctx->md_data;
-	unsigned char buf[EVP_MAX_MD_SIZE];
-
-	if (state != NULL && state->sp != NULL)
-		{
-		/*
-		 * If state->sp is not NULL then pk11_digest_final() has not
-		 * been called yet. We must call it now to free any memory
-		 * that might have been allocated in the token when
-		 * pk11_digest_init() was called. pk11_digest_final()
-		 * will return the session to the cache.
-		 */
-		if (!pk11_digest_final(ctx, buf))
-			return (0);
-		}
-
-	return (1);
-	}
-
-/*
- * Check if the new key is the same as the key object in the session. If the key
- * is the same, no need to create a new key object. Otherwise, the old key
- * object needs to be destroyed and a new one will be created. Return 1 for
- * cache hit, 0 for cache miss. Note that we must check the key length first
- * otherwise we could end up reusing a different, longer key with the same
- * prefix.
- */
-static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
-	int key_len)
-	{
-	if (sp->opdata_key_len != key_len ||
-	    memcmp(sp->opdata_key, key, key_len) != 0)
-		{
-		(void) pk11_destroy_cipher_key_objects(sp);
-		return (0);
-		}
-	return (1);
-	}
-
-/* Destroy one or more secret key objects. */
-static int pk11_destroy_cipher_key_objects(PK11_SESSION *session)
-	{
-	int ret = 0;
-	PK11_SESSION *sp = NULL;
-	PK11_SESSION *local_free_session;
-
-	if (session != NULL)
-		local_free_session = session;
-	else
-		{
-		(void) pthread_mutex_lock(session_cache[OP_CIPHER].lock);
-		local_free_session = session_cache[OP_CIPHER].head;
-		}
-
-	while ((sp = local_free_session) != NULL)
-		{
-		local_free_session = sp->next;
-
-		if (sp->opdata_cipher_key != CK_INVALID_HANDLE)
-			{
-			/*
-			 * The secret key object is created in the
-			 * global_session. See pk11_get_cipher_key().
-			 */
-			if (pk11_destroy_object(global_session,
-				sp->opdata_cipher_key, CK_FALSE) == 0)
-				goto err;
-			sp->opdata_cipher_key = CK_INVALID_HANDLE;
-			}
-		}
-	ret = 1;
-err:
-
-	if (session == NULL)
-		(void) pthread_mutex_unlock(session_cache[OP_CIPHER].lock);
-
-	return (ret);
-	}
-
-
-/*
- * Public key mechanisms optionally supported
- *
- * CKM_RSA_X_509
- * CKM_RSA_PKCS
- * CKM_DSA
- *
- * The first slot that supports at least one of those mechanisms is chosen as a
- * public key slot.
- *
- * Symmetric ciphers optionally supported
- *
- * CKM_DES3_CBC
- * CKM_DES_CBC
- * CKM_AES_CBC
- * CKM_DES3_ECB
- * CKM_DES_ECB
- * CKM_AES_ECB
- * CKM_AES_CTR
- * CKM_RC4
- * CKM_BLOWFISH_CBC
- *
- * Digests optionally supported
- *
- * CKM_MD5
- * CKM_SHA_1
- * CKM_SHA224
- * CKM_SHA256
- * CKM_SHA384
- * CKM_SHA512
- *
- * The output of this function is a set of global variables indicating which
- * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
- * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
- * variables carry information about which slot was chosen for (a) public key
- * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
- */
-static int
-pk11_choose_slots(int *any_slot_found)
-	{
-	CK_SLOT_ID_PTR pSlotList = NULL_PTR;
-	CK_ULONG ulSlotCount = 0;
-	CK_MECHANISM_INFO mech_info;
-	CK_TOKEN_INFO token_info;
-	int i;
-	CK_RV rv;
-	CK_SLOT_ID best_slot_sofar;
-	CK_BBOOL found_candidate_slot = CK_FALSE;
-	int slot_n_cipher = 0;
-	int slot_n_digest = 0;
-	CK_SLOT_ID current_slot = 0;
-	int current_slot_n_cipher = 0;
-	int current_slot_n_digest = 0;
-
-	int local_cipher_nids[PK11_CIPHER_MAX];
-	int local_digest_nids[PK11_DIGEST_MAX];
-
-	/* let's initialize the output parameter */
-	if (any_slot_found != NULL)
-		*any_slot_found = 0;
-
-	/* Get slot list for memory allocation */
-	rv = pFuncList->C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
-		return (0);
-		}
-
-	/* it's not an error if we didn't find any providers */
-	if (ulSlotCount == 0)
-		{
-		DEBUG_SLOT_SEL("%s: no crypto providers found\n", PK11_DBG);
-		return (1);
-		}
-
-	pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
-
-	if (pSlotList == NULL)
-		{
-		PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
-		return (0);
-		}
-
-	/* Get the slot list for processing */
-	rv = pFuncList->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
-		OPENSSL_free(pSlotList);
-		return (0);
-		}
-
-	DEBUG_SLOT_SEL("%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
-	DEBUG_SLOT_SEL("%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
-
-	DEBUG_SLOT_SEL("%s: == checking rand slots ==\n", PK11_DBG);
-	for (i = 0; i < ulSlotCount; i++)
-		{
-		current_slot = pSlotList[i];
-
-		DEBUG_SLOT_SEL("%s: checking slot: %d\n", PK11_DBG, i);
-		/* Check if slot has random support. */
-		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
-		if (rv != CKR_OK)
-			continue;
-
-		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
-		    token_info.label);
-
-		if (token_info.flags & CKF_RNG)
-			{
-			DEBUG_SLOT_SEL(
-			    "%s: this token has CKF_RNG flag\n", PK11_DBG);
-			pk11_have_random = CK_TRUE;
-			rand_SLOTID = current_slot;
-			break;
-			}
-		}
-
-	DEBUG_SLOT_SEL("%s: == checking pubkey slots ==\n", PK11_DBG);
-
-	pubkey_SLOTID = pSlotList[0];
-	for (i = 0; i < ulSlotCount; i++)
-		{
-		CK_BBOOL slot_has_rsa = CK_FALSE;
-		CK_BBOOL slot_has_dsa = CK_FALSE;
-		CK_BBOOL slot_has_dh = CK_FALSE;
-		current_slot = pSlotList[i];
-
-		DEBUG_SLOT_SEL("%s: checking slot: %d\n", PK11_DBG, i);
-		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
-		if (rv != CKR_OK)
-			continue;
-
-		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
-		    token_info.label);
-
-#ifndef OPENSSL_NO_RSA
-		/*
-		 * Check if this slot is capable of signing and
-		 * verifying with CKM_RSA_PKCS.
-		 */
-		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
-			&mech_info);
-
-		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
-				(mech_info.flags & CKF_VERIFY)))
-			{
-			/*
-			 * Check if this slot is capable of encryption,
-			 * decryption, sign, and verify with CKM_RSA_X_509.
-			 */
-			rv = pFuncList->C_GetMechanismInfo(current_slot,
-			    CKM_RSA_X_509, &mech_info);
-
-			if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
-			    (mech_info.flags & CKF_VERIFY) &&
-			    (mech_info.flags & CKF_ENCRYPT) &&
-			    (mech_info.flags & CKF_VERIFY_RECOVER) &&
-			    (mech_info.flags & CKF_DECRYPT)))
-				{
-				slot_has_rsa = CK_TRUE;
-				}
-			}
-#endif	/* OPENSSL_NO_RSA */
-
-#ifndef OPENSSL_NO_DSA
-		/*
-		 * Check if this slot is capable of signing and
-		 * verifying with CKM_DSA.
-		 */
-		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
-			&mech_info);
-		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
-		    (mech_info.flags & CKF_VERIFY)))
-			{
-			slot_has_dsa = CK_TRUE;
-			}
-
-#endif	/* OPENSSL_NO_DSA */
-
-#ifndef OPENSSL_NO_DH
-		/*
-		 * Check if this slot is capable of DH key generataion and
-		 * derivation.
-		 */
-		rv = pFuncList->C_GetMechanismInfo(current_slot,
-		    CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
-
-		if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
-			{
-			rv = pFuncList->C_GetMechanismInfo(current_slot,
-				CKM_DH_PKCS_DERIVE, &mech_info);
-			if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
-				{
-				slot_has_dh = CK_TRUE;
-				}
-			}
-#endif	/* OPENSSL_NO_DH */
-
-		if (!found_candidate_slot &&
-		    (slot_has_rsa || slot_has_dsa || slot_has_dh))
-			{
-			DEBUG_SLOT_SEL(
-			    "%s: potential slot: %d\n", PK11_DBG, current_slot);
-			best_slot_sofar = current_slot;
-			pk11_have_rsa = slot_has_rsa;
-			pk11_have_dsa = slot_has_dsa;
-			pk11_have_dh = slot_has_dh;
-			found_candidate_slot = CK_TRUE;
-			/*
-			 * Cache the flags for later use. We might need those if
-			 * RSA keys by reference feature is used.
-			 */
-			pubkey_token_flags = token_info.flags;
-			DEBUG_SLOT_SEL(
-			    "%s: setting found_candidate_slot to CK_TRUE\n",
-			    PK11_DBG);
-			DEBUG_SLOT_SEL("%s: best slot so far: %d\n", PK11_DBG,
-			    best_slot_sofar);
-			DEBUG_SLOT_SEL("%s: pubkey flags changed to "
-			    "%lu.\n", PK11_DBG, pubkey_token_flags);
-			}
-		else
-			{
-			DEBUG_SLOT_SEL("%s: no rsa/dsa/dh\n", PK11_DBG);
-			}
-		} /* for */
-
-	if (found_candidate_slot == CK_TRUE)
-		{
-		pubkey_SLOTID = best_slot_sofar;
-		}
-
-	found_candidate_slot = CK_FALSE;
-	best_slot_sofar = 0;
-
-	DEBUG_SLOT_SEL("%s: == checking cipher/digest ==\n", PK11_DBG);
-
-	SLOTID = pSlotList[0];
-	for (i = 0; i < ulSlotCount; i++)
-		{
-		DEBUG_SLOT_SEL("%s: checking slot: %d\n", PK11_DBG, i);
-
-		current_slot = pSlotList[i];
-		current_slot_n_cipher = 0;
-		current_slot_n_digest = 0;
-		(void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids));
-		(void) memset(local_digest_nids, 0, sizeof (local_digest_nids));
-
-		pk11_find_symmetric_ciphers(pFuncList, current_slot,
-		    &current_slot_n_cipher, local_cipher_nids);
-
-		pk11_find_digests(pFuncList, current_slot,
-		    &current_slot_n_digest, local_digest_nids);
-
-		DEBUG_SLOT_SEL("%s: current_slot_n_cipher %d\n", PK11_DBG,
-			current_slot_n_cipher);
-		DEBUG_SLOT_SEL("%s: current_slot_n_digest %d\n", PK11_DBG,
-			current_slot_n_digest);
-		DEBUG_SLOT_SEL("%s: best cipher/digest slot so far: %d\n",
-			PK11_DBG, best_slot_sofar);
-
-		/*
-		 * If the current slot supports more ciphers/digests than
-		 * the previous best one we change the current best to this one,
-		 * otherwise leave it where it is.
-		 */
-		if ((current_slot_n_cipher + current_slot_n_digest) >
-		    (slot_n_cipher + slot_n_digest))
-			{
-			DEBUG_SLOT_SEL("%s: changing best slot to %d\n",
-				PK11_DBG, current_slot);
-			best_slot_sofar = SLOTID = current_slot;
-			cipher_count = slot_n_cipher = current_slot_n_cipher;
-			digest_count = slot_n_digest = current_slot_n_digest;
-			(void) memcpy(cipher_nids, local_cipher_nids,
-			    sizeof (local_cipher_nids));
-			(void) memcpy(digest_nids, local_digest_nids,
-			    sizeof (local_digest_nids));
-			}
-		}
-
-	DEBUG_SLOT_SEL("%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
-	DEBUG_SLOT_SEL("%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
-	DEBUG_SLOT_SEL("%s: chosen cipher/digest slot: %d\n", PK11_DBG, SLOTID);
-	DEBUG_SLOT_SEL("%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
-	DEBUG_SLOT_SEL("%s: pk11_have_dsa %d\n", PK11_DBG, pk11_have_dsa);
-	DEBUG_SLOT_SEL("%s: pk11_have_dh %d\n", PK11_DBG, pk11_have_dh);
-	DEBUG_SLOT_SEL("%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
-	DEBUG_SLOT_SEL("%s: cipher_count %d\n", PK11_DBG, cipher_count);
-	DEBUG_SLOT_SEL("%s: digest_count %d\n", PK11_DBG, digest_count);
-
-	if (pSlotList != NULL)
-		OPENSSL_free(pSlotList);
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-	OPENSSL_free(hw_cnids);
-	OPENSSL_free(hw_dnids);
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-
-	if (any_slot_found != NULL)
-		*any_slot_found = 1;
-	return (1);
-	}
-
-static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR pflist,
-    int slot_id, int *current_slot_n_cipher, int *local_cipher_nids,
-    PK11_CIPHER *cipher)
-	{
-	CK_MECHANISM_INFO mech_info;
-	CK_RV rv;
-
-	DEBUG_SLOT_SEL("%s: checking mech: %x", PK11_DBG, cipher->mech_type);
-	rv = pflist->C_GetMechanismInfo(slot_id, cipher->mech_type, &mech_info);
-
-	if (rv != CKR_OK)
-		{
-		DEBUG_SLOT_SEL(" not found\n");
-		return;
-		}
-
-	if ((mech_info.flags & CKF_ENCRYPT) &&
-	    (mech_info.flags & CKF_DECRYPT))
-		{
-		if (mech_info.ulMinKeySize > cipher->min_key_len ||
-		    mech_info.ulMaxKeySize < cipher->max_key_len)
-			{
-			DEBUG_SLOT_SEL(" engine key size range <%i-%i> does not"
-			    " match mech range <%lu-%lu>\n",
-			    cipher->min_key_len, cipher->max_key_len,
-			    mech_info.ulMinKeySize, mech_info.ulMaxKeySize);
-			return;
-			}
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-		if (nid_in_table(cipher->nid, hw_cnids))
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-			{
-			DEBUG_SLOT_SEL(" usable\n");
-			local_cipher_nids[(*current_slot_n_cipher)++] =
-			    cipher->nid;
-			}
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-		else
-			{
-			DEBUG_SLOT_SEL(
-			    " rejected, software implementation only\n");
-			}
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-		}
-	else
-		{
-		DEBUG_SLOT_SEL(" unusable\n");
-		}
-
-	return;
-	}
-
-static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
-    int *current_slot_n_digest, int *local_digest_nids, PK11_DIGEST *digest)
-	{
-	CK_MECHANISM_INFO mech_info;
-	CK_RV rv;
-
-	DEBUG_SLOT_SEL("%s: checking mech: %x", PK11_DBG, digest->mech_type);
-	rv = pflist->C_GetMechanismInfo(slot_id, digest->mech_type, &mech_info);
-
-	if (rv != CKR_OK)
-		{
-		DEBUG_SLOT_SEL(" not found\n");
-		return;
-		}
-
-	if (mech_info.flags & CKF_DIGEST)
-		{
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-		if (nid_in_table(digest->nid, hw_dnids))
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-			{
-			DEBUG_SLOT_SEL(" usable\n");
-			local_digest_nids[(*current_slot_n_digest)++] =
-			    digest->nid;
-			}
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-		else
-			{
-			DEBUG_SLOT_SEL(
-			    " rejected, software implementation only\n");
-			}
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-		}
-	else
-		{
-		DEBUG_SLOT_SEL(" unusable\n");
-		}
-
-	return;
-	}
-
-#ifdef	SOLARIS_AES_CTR
-/* create a new NID when we have no OID for that mechanism */
-static int pk11_add_NID(char *sn, char *ln)
-	{
-	ASN1_OBJECT *o;
-	int nid;
-
-	if ((o = ASN1_OBJECT_create(OBJ_new_nid(1), (unsigned char *)"",
-	    1, sn, ln)) == NULL)
-		{
-		return (0);
-		}
-
-	/* will return NID_undef on error */
-	nid = OBJ_add_object(o);
-	ASN1_OBJECT_free(o);
-
-	return (nid);
-	}
-
-/*
- * Create new NIDs for AES counter mode. OpenSSL doesn't support them now so we
- * have to help ourselves here.
- */
-static int pk11_add_aes_ctr_NIDs(void)
-	{
-	/* are we already set? */
-	if (NID_aes_256_ctr != NID_undef)
-		return (1);
-
-	/*
-	 * There are no official names for AES counter modes yet so we just
-	 * follow the format of those that exist.
-	 */
-	if ((NID_aes_128_ctr = pk11_add_NID("AES-128-CTR", "aes-128-ctr")) ==
-	    NID_undef)
-		goto err;
-	ciphers[PK11_AES_128_CTR].nid = pk11_aes_128_ctr.nid = NID_aes_128_ctr;
-	if ((NID_aes_192_ctr = pk11_add_NID("AES-192-CTR", "aes-192-ctr")) ==
-	    NID_undef)
-		goto err;
-	ciphers[PK11_AES_192_CTR].nid = pk11_aes_192_ctr.nid = NID_aes_192_ctr;
-	if ((NID_aes_256_ctr = pk11_add_NID("AES-256-CTR", "aes-256-ctr")) ==
-	    NID_undef)
-		goto err;
-	ciphers[PK11_AES_256_CTR].nid = pk11_aes_256_ctr.nid = NID_aes_256_ctr;
-	return (1);
-
-err:
-	PK11err(PK11_F_ADD_AES_CTR_NIDS, PK11_R_ADD_NID_FAILED);
-	return (0);
-	}
-#endif	/* SOLARIS_AES_CTR */
-
-/* Find what symmetric ciphers this slot supports. */
-static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
-    CK_SLOT_ID current_slot, int *current_slot_n_cipher, int *local_cipher_nids)
-	{
-	int i;
-
-	for (i = 0; i < PK11_CIPHER_MAX; ++i)
-		{
-		pk11_get_symmetric_cipher(pflist, current_slot,
-		    current_slot_n_cipher, local_cipher_nids, &ciphers[i]);
-		}
-	}
-
-/* Find what digest algorithms this slot supports. */
-static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
-    CK_SLOT_ID current_slot, int *current_slot_n_digest, int *local_digest_nids)
-	{
-	int i;
-
-	for (i = 0; i < PK11_DIGEST_MAX; ++i)
-		{
-		pk11_get_digest(pflist, current_slot, current_slot_n_digest,
-		    local_digest_nids, &digests[i]);
-		}
-	}
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-/*
- * It would be great if we could use pkcs11_kernel directly since this library
- * offers hardware slots only. That's the easiest way to achieve the situation
- * where we use the hardware accelerators when present and OpenSSL native code
- * otherwise. That presumes the fact that OpenSSL native code is faster than the
- * code in the soft token. It's a logical assumption - Crypto Framework has some
- * inherent overhead so going there for the software implementation of a
- * mechanism should be logically slower in contrast to the OpenSSL native code,
- * presuming that both implementations are of similar speed. For example, the
- * soft token for AES is roughly three times slower than OpenSSL for 64 byte
- * blocks and still 20% slower for 8KB blocks. So, if we want to ship products
- * that use the PKCS#11 engine by default, we must somehow avoid that regression
- * on machines without hardware acceleration. That's why switching to the
- * pkcs11_kernel library seems like a very good idea.
- *
- * The problem is that OpenSSL built with SunStudio is roughly 2x slower for
- * asymmetric operations (RSA/DSA/DH) than the soft token built with the same
- * compiler. That means that if we switched to pkcs11_kernel from the libpkcs11
- * library, we would have had a performance regression on machines without
- * hardware acceleration for asymmetric operations for all applications that use
- * the PKCS#11 engine. There is one such application - Apache web server since
- * it's shipped configured to use the PKCS#11 engine by default. Having said
- * that, we can't switch to the pkcs11_kernel library now and have to come with
- * a solution that, on non-accelerated machines, uses the OpenSSL native code
- * for all symmetric ciphers and digests while it uses the soft token for
- * asymmetric operations.
- *
- * This is the idea: dlopen() pkcs11_kernel directly and find out what
- * mechanisms are there. We don't care about duplications (more slots can
- * support the same mechanism), we just want to know what mechanisms can be
- * possibly supported in hardware on that particular machine. As said before,
- * pkcs11_kernel will show you hardware providers only.
- *
- * Then, we rely on the fact that since we use libpkcs11 library we will find
- * the metaslot. When we go through the metaslot's mechanisms for symmetric
- * ciphers and digests, we check that any found mechanism is in the table
- * created using the pkcs11_kernel library. So, as a result we have two arrays
- * of mechanisms that were advertised as supported in hardware which was the
- * goal of that whole exercise. Thus, we can use libpkcs11 but avoid soft token
- * code for symmetric ciphers and digests. See pk11_choose_slots() for more
- * information.
- *
- * This is Solaris specific code, if SOLARIS_HW_SLOT_SELECTION is not defined
- * the code won't be used.
- */
-#if defined(__sparcv9) || defined(__x86_64) || defined(__amd64)
-static const char pkcs11_kernel[] = "/usr/lib/security/64/pkcs11_kernel.so.1";
-#else
-static const char pkcs11_kernel[] = "/usr/lib/security/pkcs11_kernel.so.1";
-#endif
-
-/*
- * Check hardware capabilities of the machines. The output are two lists,
- * hw_cnids and hw_dnids, that contain hardware mechanisms found in all hardware
- * providers together. They are not sorted and may contain duplicate mechanisms.
- */
-static int check_hw_mechanisms(void)
-	{
-	int i;
-	CK_RV rv;
-	void *handle;
-	CK_C_GetFunctionList p;
-	CK_TOKEN_INFO token_info;
-	CK_ULONG ulSlotCount = 0;
-	int n_cipher = 0, n_digest = 0;
-	CK_FUNCTION_LIST_PTR pflist = NULL;
-	CK_SLOT_ID_PTR pSlotList = NULL_PTR;
-	int *tmp_hw_cnids = NULL, *tmp_hw_dnids = NULL;
-	int hw_ctable_size, hw_dtable_size;
-
-	DEBUG_SLOT_SEL("%s: SOLARIS_HW_SLOT_SELECTION code running\n",
-	    PK11_DBG);
-	/*
-	 * Use RTLD_GROUP to limit the pkcs11_kernel provider to its own
-	 * symbols, which prevents it from mistakenly accessing C_* functions
-	 * from the top-level PKCS#11 library.
-	 */
-	if ((handle = dlopen(pkcs11_kernel, RTLD_LAZY | RTLD_GROUP)) == NULL)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-
-	if ((p = (CK_C_GetFunctionList)dlsym(handle,
-	    PK11_GET_FUNCTION_LIST)) == NULL)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-
-	/* get the full function list from the loaded library */
-	if (p(&pflist) != CKR_OK)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-
-	rv = pflist->C_Initialize(NULL_PTR);
-	if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
-		{
-		PK11err_add_data(PK11_F_CHECK_HW_MECHANISMS,
-		    PK11_R_INITIALIZE, rv);
-		goto err;
-		}
-
-	if (pflist->C_GetSlotList(0, NULL_PTR, &ulSlotCount) != CKR_OK)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
-		goto err;
-		}
-
-	/* no slots, set the hw mechanism tables as empty */
-	if (ulSlotCount == 0)
-		{
-		DEBUG_SLOT_SEL("%s: no hardware mechanisms found\n", PK11_DBG);
-		hw_cnids = OPENSSL_malloc(sizeof (int));
-		hw_dnids = OPENSSL_malloc(sizeof (int));
-		if (hw_cnids == NULL || hw_dnids == NULL)
-			{
-			PK11err(PK11_F_CHECK_HW_MECHANISMS,
-			    PK11_R_MALLOC_FAILURE);
-			return (0);
-			}
-		/* this means empty tables */
-		hw_cnids[0] = NID_undef;
-		hw_dnids[0] = NID_undef;
-		return (1);
-		}
-
-	pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
-	if (pSlotList == NULL)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	/* Get the slot list for processing */
-	if (pflist->C_GetSlotList(0, pSlotList, &ulSlotCount) != CKR_OK)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
-		goto err;
-		}
-
-	/*
-	 * We don't care about duplicate mechanisms in multiple slots and also
-	 * reserve one slot for the terminal NID_undef which we use to stop the
-	 * search.
-	 */
-	hw_ctable_size = ulSlotCount * PK11_CIPHER_MAX + 1;
-	hw_dtable_size = ulSlotCount * PK11_DIGEST_MAX + 1;
-	tmp_hw_cnids = OPENSSL_malloc(hw_ctable_size * sizeof (int));
-	tmp_hw_dnids = OPENSSL_malloc(hw_dtable_size * sizeof (int));
-	if (tmp_hw_cnids == NULL || tmp_hw_dnids == NULL)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	/*
-	 * Do not use memset since we should not rely on the fact that NID_undef
-	 * is zero now.
-	 */
-	for (i = 0; i < hw_ctable_size; ++i)
-		tmp_hw_cnids[i] = NID_undef;
-	for (i = 0; i < hw_dtable_size; ++i)
-		tmp_hw_dnids[i] = NID_undef;
-
-	DEBUG_SLOT_SEL("%s: provider: %s\n", PK11_DBG, pkcs11_kernel);
-	DEBUG_SLOT_SEL("%s: found %d hardware slots\n", PK11_DBG, ulSlotCount);
-	DEBUG_SLOT_SEL("%s: now looking for mechs supported in hw\n",
-	    PK11_DBG);
-
-	for (i = 0; i < ulSlotCount; i++)
-		{
-		if (pflist->C_GetTokenInfo(pSlotList[i], &token_info) != CKR_OK)
-			continue;
-
-		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
-		    token_info.label);
-
-		/*
-		 * We are filling the hw mech tables here. Global tables are
-		 * still NULL so all mechanisms are put into tmp tables.
-		 */
-		pk11_find_symmetric_ciphers(pflist, pSlotList[i],
-		    &n_cipher, tmp_hw_cnids);
-		pk11_find_digests(pflist, pSlotList[i],
-		    &n_digest, tmp_hw_dnids);
-		}
-
-	/*
-	 * Since we are part of a library (libcrypto.so), calling this function
-	 * may have side-effects. Also, C_Finalize() is triggered by
-	 * dlclose(3C).
-	 */
-#if 0
-	pflist->C_Finalize(NULL);
-#endif
-	OPENSSL_free(pSlotList);
-	(void) dlclose(handle);
-	hw_cnids = tmp_hw_cnids;
-	hw_dnids = tmp_hw_dnids;
-
-	DEBUG_SLOT_SEL("%s: hw mechs check complete\n", PK11_DBG);
-	return (1);
-
-err:
-	if (pSlotList != NULL)
-		OPENSSL_free(pSlotList);
-	if (tmp_hw_cnids != NULL)
-		OPENSSL_free(tmp_hw_cnids);
-	if (tmp_hw_dnids != NULL)
-		OPENSSL_free(tmp_hw_dnids);
-
-	return (0);
-	}
-
-/*
- * Check presence of a NID in the table of NIDs. The table may be NULL (i.e.,
- * non-existent).
- */
-static int nid_in_table(int nid, int *nid_table)
-	{
-	int i = 0;
-
-	/*
-	 * a special case. NULL means that we are initializing a new
-	 * table.
-	 */
-	if (nid_table == NULL)
-		return (1);
-
-	/*
-	 * the table is never full, there is always at least one
-	 * NID_undef.
-	 */
-	while (nid_table[i] != NID_undef)
-		{
-		if (nid_table[i++] == nid)
-			{
-			DEBUG_SLOT_SEL(" (NID %d in hw table, idx %d)", nid, i);
-			return (1);
-			}
-		}
-
-	return (0);
-	}
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-
-#endif	/* OPENSSL_NO_HW_PK11 */
-#endif	/* OPENSSL_NO_HW */
--- a/components/openssl/openssl-0.9.8-fips-140/engines/pkcs11/e_pk11.h	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,248 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- *
- */
-
-/* crypto/engine/e_pk11.h */
-/*
- * This product includes software developed by the OpenSSL Project for
- * use in the OpenSSL Toolkit (http://www.openssl.org/).
- *
- * This project also referenced hw_pkcs11-0.9.7b.patch written by
- * Afchine Madjlessi.
- */
-/*
- * ====================================================================
- * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    [email protected]
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
-#ifndef	E_PK11_H
-#define	E_PK11_H
-
-#include "e_pk11_err.h"
-
-/* max byte length of a symetric key we support */
-#define	PK11_KEY_LEN_MAX			32
-
-/*
- * This structure encapsulates all reusable information for a PKCS#11
- * session. A list of these objects is created on behalf of the
- * calling application using an on-demand method. Each operation
- * type (see PK11_OPTYPE below) has its own per-process list.
- * Each of the lists is basically a cache for faster PKCS#11 object
- * access to avoid expensive C_Find{,Init,Final}Object() calls.
- *
- * When a new request comes in, an object will be taken from the list
- * (if there is one) or a new one is created to handle the request
- * (if the list is empty). See pk11_get_session() on how it is done.
- */
-typedef struct PK11_st_SESSION
-	{
-	struct PK11_st_SESSION	*next;
-	CK_SESSION_HANDLE	session;	/* PK11 session handle */
-	pid_t			pid;		/* Current process ID */
-	CK_BBOOL		persistent;	/* is that a keystore object? */
-	union
-		{
-#ifndef OPENSSL_NO_RSA
-		struct
-			{
-			CK_OBJECT_HANDLE	rsa_pub_key; /* pub handle */
-			CK_OBJECT_HANDLE	rsa_priv_key; /* priv handle */
-			RSA			*rsa_pub; /* pub key addr */
-			BIGNUM			*rsa_n_num; /* pub modulus */
-			BIGNUM			*rsa_e_num; /* pub exponent */
-			RSA			*rsa_priv; /* priv key addr */
-			BIGNUM			*rsa_d_num; /* priv exponent */
-			} u_RSA;
-#endif /* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-		struct
-			{
-			CK_OBJECT_HANDLE	dsa_pub_key; /* pub handle */
-			CK_OBJECT_HANDLE	dsa_priv_key; /* priv handle */
-			DSA			*dsa_pub; /* pub key addr */
-			BIGNUM			*dsa_pub_num; /* pub key */
-			DSA			*dsa_priv; /* priv key addr */
-			BIGNUM			*dsa_priv_num; /* priv key */
-			} u_DSA;
-#endif /* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-		struct
-			{
-			CK_OBJECT_HANDLE	dh_key; /* key handle */
-			DH			*dh; /* dh key addr */
-			BIGNUM			*dh_priv_num; /* priv dh key */
-			} u_DH;
-#endif /* OPENSSL_NO_DH */
-		struct
-			{
-			CK_OBJECT_HANDLE	cipher_key; /* key handle */
-			unsigned char		key[PK11_KEY_LEN_MAX];
-			int			key_len; /* priv key len */
-			int			encrypt; /* 1/0 enc/decr */
-			} u_cipher;
-		} opdata_u;
-	} PK11_SESSION;
-
-#define	opdata_rsa_pub_key	opdata_u.u_RSA.rsa_pub_key
-#define	opdata_rsa_priv_key	opdata_u.u_RSA.rsa_priv_key
-#define	opdata_rsa_pub		opdata_u.u_RSA.rsa_pub
-#define	opdata_rsa_priv		opdata_u.u_RSA.rsa_priv
-#define	opdata_rsa_n_num	opdata_u.u_RSA.rsa_n_num
-#define	opdata_rsa_e_num	opdata_u.u_RSA.rsa_e_num
-#define	opdata_rsa_d_num	opdata_u.u_RSA.rsa_d_num
-#define	opdata_dsa_pub_key	opdata_u.u_DSA.dsa_pub_key
-#define	opdata_dsa_priv_key	opdata_u.u_DSA.dsa_priv_key
-#define	opdata_dsa_pub		opdata_u.u_DSA.dsa_pub
-#define	opdata_dsa_pub_num	opdata_u.u_DSA.dsa_pub_num
-#define	opdata_dsa_priv		opdata_u.u_DSA.dsa_priv
-#define	opdata_dsa_priv_num	opdata_u.u_DSA.dsa_priv_num
-#define	opdata_dh_key		opdata_u.u_DH.dh_key
-#define	opdata_dh		opdata_u.u_DH.dh
-#define	opdata_dh_priv_num	opdata_u.u_DH.dh_priv_num
-#define	opdata_cipher_key	opdata_u.u_cipher.cipher_key
-#define	opdata_key		opdata_u.u_cipher.key
-#define	opdata_key_len		opdata_u.u_cipher.key_len
-#define	opdata_encrypt		opdata_u.u_cipher.encrypt
-
-/*
- * We have 3 different groups of operation types:
- *   1) asymmetric operations
- *   2) random operations
- *   3) symmetric and digest operations
- *
- * This division into groups stems from the fact that it's common that hardware
- * providers may support operations from one group only. For example, hardware
- * providers on UltraSPARC T2, n2rng(7d), ncp(7d), and n2cp(7d), each support
- * only a single group of operations.
- *
- * For every group a different slot can be chosen. That means that we must have
- * at least 3 different lists of cached PKCS#11 sessions since sessions from
- * different groups may be initialized in different slots.
- *
- * To provide locking granularity in multithreaded environment, the groups are
- * further splitted into types with each type having a separate session cache.
- */
-typedef enum PK11_OPTYPE_ENUM
-	{
-	OP_RAND,
-	OP_RSA,
-	OP_DSA,
-	OP_DH,
-	OP_CIPHER,
-	OP_DIGEST,
-	OP_MAX
-	} PK11_OPTYPE;
-
-/*
- * This structure contains the heads of the lists forming the object caches
- * and locks associated with the lists.
- */
-typedef struct PK11_st_CACHE
-	{
-	PK11_SESSION *head;
-	pthread_mutex_t *lock;
-	} PK11_CACHE;
-
-/* structure for tracking handles of asymmetric key objects */
-typedef struct PK11_active_st
-	{
-	CK_OBJECT_HANDLE h;
-	unsigned int refcnt;
-	struct PK11_active_st *prev;
-	struct PK11_active_st *next;
-	} PK11_active;
-
-extern pthread_mutex_t *find_lock[];
-extern PK11_active *active_list[];
-/*
- * These variables are specific for the RSA keys by reference code. See
- * e_pk11_pub.c for explanation.
- */
-extern char *passphrasedialog;
-extern CK_FLAGS pubkey_token_flags;
-
-#define	LOCK_OBJSTORE(alg_type)	\
-	(void) pthread_mutex_lock(find_lock[alg_type])
-#define	UNLOCK_OBJSTORE(alg_type)	\
-	(void) pthread_mutex_unlock(find_lock[alg_type])
-
-extern PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
-extern void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
-
-#ifndef OPENSSL_NO_RSA
-extern int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
-extern int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
-extern int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
-extern EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *pubkey_file,
-	UI_METHOD *ui_method, void *callback_data);
-extern EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
-	UI_METHOD *ui_method, void *callback_data);
-extern RSA_METHOD *PK11_RSA(void);
-#endif /* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-extern int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
-extern int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
-extern int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
-extern DSA_METHOD *PK11_DSA(void);
-#endif /* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-extern int pk11_destroy_dh_key_objects(PK11_SESSION *session);
-extern int pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock);
-extern DH_METHOD *PK11_DH(void);
-#endif /* OPENSSL_NO_DH */
-
-extern CK_FUNCTION_LIST_PTR pFuncList;
-
-#endif /* E_PK11_H */
--- a/components/openssl/openssl-0.9.8-fips-140/engines/pkcs11/e_pk11_err.c	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,307 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- *
- */
-
-/* crypto/engine/e_pk11_err.c */
-/*
- * This product includes software developed by the OpenSSL Project for
- * use in the OpenSSL Toolkit (http://www.openssl.org/).
- *
- * This project also referenced hw_pkcs11-0.9.7b.patch written by
- * Afchine Madjlessi.
- */
-/*
- * ====================================================================
- * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    [email protected]
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
-#include <stdio.h>
-#include <openssl/err.h>
-#include "e_pk11_err.h"
-
-/* BEGIN ERROR CODES */
-#ifndef OPENSSL_NO_ERR
-static ERR_STRING_DATA pk11_str_functs[]=
-{
-{ ERR_PACK(0, PK11_F_INIT, 0),			"PK11_INIT"},
-{ ERR_PACK(0, PK11_F_FINISH, 0),		"PK11_FINISH"},
-{ ERR_PACK(0, PK11_F_DESTROY, 0),		"PK11_DESTROY"},
-{ ERR_PACK(0, PK11_F_CTRL, 0),			"PK11_CTRL"},
-{ ERR_PACK(0, PK11_F_RSA_INIT, 0),		"PK11_RSA_INIT"},
-{ ERR_PACK(0, PK11_F_RSA_FINISH, 0),		"PK11_RSA_FINISH"},
-{ ERR_PACK(0, PK11_F_GET_PUB_RSA_KEY, 0),	"PK11_GET_PUB_RSA_KEY"},
-{ ERR_PACK(0, PK11_F_GET_PRIV_RSA_KEY, 0),	"PK11_GET_PRIV_RSA_KEY"},
-{ ERR_PACK(0, PK11_F_RSA_GEN_KEY, 0),		"PK11_RSA_GEN_KEY"},
-{ ERR_PACK(0, PK11_F_RSA_PUB_ENC, 0),		"PK11_RSA_PUB_ENC"},
-{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC, 0),		"PK11_RSA_PRIV_ENC"},
-{ ERR_PACK(0, PK11_F_RSA_PUB_DEC, 0),		"PK11_RSA_PUB_DEC"},
-{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC, 0),		"PK11_RSA_PRIV_DEC"},
-{ ERR_PACK(0, PK11_F_RSA_SIGN, 0),		"PK11_RSA_SIGN"},
-{ ERR_PACK(0, PK11_F_RSA_VERIFY, 0),		"PK11_RSA_VERIFY"},
-{ ERR_PACK(0, PK11_F_RAND_ADD, 0),		"PK11_RAND_ADD"},
-{ ERR_PACK(0, PK11_F_RAND_BYTES, 0),		"PK11_RAND_BYTES"},
-{ ERR_PACK(0, PK11_F_GET_SESSION, 0),		"PK11_GET_SESSION"},
-{ ERR_PACK(0, PK11_F_FREE_SESSION, 0),		"PK11_FREE_SESSION"},
-{ ERR_PACK(0, PK11_F_LOAD_PUBKEY, 0),		"PK11_LOAD_PUBKEY"},
-{ ERR_PACK(0, PK11_F_LOAD_PRIVKEY, 0),		"PK11_LOAD_PRIV_KEY"},
-{ ERR_PACK(0, PK11_F_RSA_PUB_ENC_LOW, 0),	"PK11_RSA_PUB_ENC_LOW"},
-{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC_LOW, 0),	"PK11_RSA_PRIV_ENC_LOW"},
-{ ERR_PACK(0, PK11_F_RSA_PUB_DEC_LOW, 0),	"PK11_RSA_PUB_DEC_LOW"},
-{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC_LOW, 0),	"PK11_RSA_PRIV_DEC_LOW"},
-{ ERR_PACK(0, PK11_F_DSA_SIGN, 0),		"PK11_DSA_SIGN"},
-{ ERR_PACK(0, PK11_F_DSA_VERIFY, 0),		"PK11_DSA_VERIFY"},
-{ ERR_PACK(0, PK11_F_DSA_INIT, 0),		"PK11_DSA_INIT"},
-{ ERR_PACK(0, PK11_F_DSA_FINISH, 0),		"PK11_DSA_FINISH"},
-{ ERR_PACK(0, PK11_F_GET_PUB_DSA_KEY, 0),	"PK11_GET_PUB_DSA_KEY"},
-{ ERR_PACK(0, PK11_F_GET_PRIV_DSA_KEY, 0),	"PK11_GET_PRIV_DSA_KEY"},
-{ ERR_PACK(0, PK11_F_DH_INIT, 0),		"PK11_DH_INIT"},
-{ ERR_PACK(0, PK11_F_DH_FINISH, 0),		"PK11_DH_FINISH"},
-{ ERR_PACK(0, PK11_F_MOD_EXP_DH, 0),		"PK11_MOD_EXP_DH"},
-{ ERR_PACK(0, PK11_F_GET_DH_KEY, 0),		"PK11_GET_DH_KEY"},
-{ ERR_PACK(0, PK11_F_FREE_ALL_SESSIONS, 0),	"PK11_FREE_ALL_SESSIONS"},
-{ ERR_PACK(0, PK11_F_SETUP_SESSION, 0),		"PK11_SETUP_SESSION"},
-{ ERR_PACK(0, PK11_F_DESTROY_OBJECT, 0),	"PK11_DESTROY_OBJECT"},
-{ ERR_PACK(0, PK11_F_CIPHER_INIT, 0),		"PK11_CIPHER_INIT"},
-{ ERR_PACK(0, PK11_F_CIPHER_DO_CIPHER, 0),	"PK11_CIPHER_DO_CIPHER"},
-{ ERR_PACK(0, PK11_F_GET_CIPHER_KEY, 0),	"PK11_GET_CIPHER_KEY"},
-{ ERR_PACK(0, PK11_F_DIGEST_INIT, 0),		"PK11_DIGEST_INIT"},
-{ ERR_PACK(0, PK11_F_DIGEST_UPDATE, 0),		"PK11_DIGEST_UPDATE"},
-{ ERR_PACK(0, PK11_F_DIGEST_FINAL, 0),		"PK11_DIGEST_FINAL"},
-{ ERR_PACK(0, PK11_F_CHOOSE_SLOT, 0),		"PK11_CHOOSE_SLOT"},
-{ ERR_PACK(0, PK11_F_CIPHER_FINAL, 0),		"PK11_CIPHER_FINAL"},
-{ ERR_PACK(0, PK11_F_LIBRARY_INIT, 0),		"PK11_LIBRARY_INIT"},
-{ ERR_PACK(0, PK11_F_LOAD, 0),			"ENGINE_LOAD_PK11"},
-{ ERR_PACK(0, PK11_F_DH_GEN_KEY, 0),		"PK11_DH_GEN_KEY"},
-{ ERR_PACK(0, PK11_F_DH_COMP_KEY, 0),		"PK11_DH_COMP_KEY"},
-{ ERR_PACK(0, PK11_F_DIGEST_COPY, 0),		"PK11_DIGEST_COPY"},
-{ ERR_PACK(0, PK11_F_CIPHER_CLEANUP, 0),	"PK11_CIPHER_CLEANUP"},
-{ ERR_PACK(0, PK11_F_ACTIVE_ADD, 0),		"PK11_ACTIVE_ADD"},
-{ ERR_PACK(0, PK11_F_ACTIVE_DELETE, 0),		"PK11_ACTIVE_DELETE"},
-{ ERR_PACK(0, PK11_F_CHECK_HW_MECHANISMS, 0),	"PK11_CHECK_HW_MECHANISMS"},
-{ ERR_PACK(0, PK11_F_INIT_SYMMETRIC, 0),	"PK11_INIT_SYMMETRIC"},
-{ ERR_PACK(0, PK11_F_ADD_AES_CTR_NIDS, 0),	"PK11_ADD_AES_CTR_NIDS"},
-{ ERR_PACK(0, PK11_F_INIT_ALL_LOCKS, 0),	"PK11_INIT_ALL_LOCKS"},
-{ ERR_PACK(0, PK11_F_RETURN_SESSION, 0),	"PK11_RETURN_SESSION"},
-{ ERR_PACK(0, PK11_F_GET_PIN, 0),		"PK11_GET_PIN"},
-{ ERR_PACK(0, PK11_F_FIND_ONE_OBJECT, 0),	"PK11_FIND_ONE_OBJECT"},
-{ ERR_PACK(0, PK11_F_CHECK_TOKEN_ATTRS, 0),	"PK11_CHECK_TOKEN_ATTRS"},
-{ ERR_PACK(0, PK11_F_CACHE_PIN, 0),		"PK11_CACHE_PIN"},
-{ ERR_PACK(0, PK11_F_MLOCK_PIN_IN_MEMORY, 0),	"PK11_MLOCK_PIN_IN_MEMORY"},
-{ ERR_PACK(0, PK11_F_TOKEN_LOGIN, 0),		"PK11_TOKEN_LOGIN"},
-{ ERR_PACK(0, PK11_F_TOKEN_RELOGIN, 0),		"PK11_TOKEN_RELOGIN"},
-{ ERR_PACK(0, PK11_F_RUN_ASKPASS, 0),		"PK11_F_RUN_ASKPASS"},
-{ 0, NULL}
-};
-
-static ERR_STRING_DATA pk11_str_reasons[]=
-{
-{ PK11_R_ALREADY_LOADED,		"PKCS#11 DSO already loaded"},
-{ PK11_R_DSO_FAILURE,			"unable to load PKCS#11 DSO"},
-{ PK11_R_NOT_LOADED,			"PKCS#11 DSO not loaded"},
-{ PK11_R_PASSED_NULL_PARAMETER,		"null parameter passed"},
-{ PK11_R_COMMAND_NOT_IMPLEMENTED,	"command not implemented"},
-{ PK11_R_INITIALIZE,			"C_Initialize failed"},
-{ PK11_R_FINALIZE,			"C_Finalize failed"},
-{ PK11_R_GETINFO,			"C_GetInfo faile"},
-{ PK11_R_GETSLOTLIST,			"C_GetSlotList failed"},
-{ PK11_R_NO_MODULUS_OR_NO_EXPONENT,	"no modulus or no exponent"},
-{ PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID,	"attr sensitive or invalid"},
-{ PK11_R_GETATTRIBUTVALUE,		"C_GetAttributeValue failed"},
-{ PK11_R_NO_MODULUS,			"no modulus"},
-{ PK11_R_NO_EXPONENT,			"no exponent"},
-{ PK11_R_FINDOBJECTSINIT,		"C_FindObjectsInit failed"},
-{ PK11_R_FINDOBJECTS,			"C_FindObjects failed"},
-{ PK11_R_FINDOBJECTSFINAL,		"C_FindObjectsFinal failed"},
-{ PK11_R_CREATEOBJECT,			"C_CreateObject failed"},
-{ PK11_R_DESTROYOBJECT,			"C_DestroyObject failed"},
-{ PK11_R_OPENSESSION,			"C_OpenSession failed"},
-{ PK11_R_CLOSESESSION,			"C_CloseSession failed"},
-{ PK11_R_ENCRYPTINIT,			"C_EncryptInit failed"},
-{ PK11_R_ENCRYPT,			"C_Encrypt failed"},
-{ PK11_R_SIGNINIT,			"C_SignInit failed"},
-{ PK11_R_SIGN,				"C_Sign failed"},
-{ PK11_R_DECRYPTINIT,			"C_DecryptInit failed"},
-{ PK11_R_DECRYPT,			"C_Decrypt failed"},
-{ PK11_R_VERIFYINIT,			"C_VerifyRecover failed"},
-{ PK11_R_VERIFY,			"C_Verify failed"},
-{ PK11_R_VERIFYRECOVERINIT,		"C_VerifyRecoverInit failed"},
-{ PK11_R_VERIFYRECOVER,			"C_VerifyRecover failed"},
-{ PK11_R_GEN_KEY,			"C_GenerateKeyPair failed"},
-{ PK11_R_SEEDRANDOM,			"C_SeedRandom failed"},
-{ PK11_R_GENERATERANDOM,		"C_GenerateRandom failed"},
-{ PK11_R_INVALID_MESSAGE_LENGTH,	"invalid message length"},
-{ PK11_R_UNKNOWN_ALGORITHM_TYPE,	"unknown algorithm type"},
-{ PK11_R_UNKNOWN_ASN1_OBJECT_ID,	"unknown asn1 onject id"},
-{ PK11_R_UNKNOWN_PADDING_TYPE,		"unknown padding type"},
-{ PK11_R_PADDING_CHECK_FAILED,		"padding check failed"},
-{ PK11_R_DIGEST_TOO_BIG,		"digest too big"},
-{ PK11_R_MALLOC_FAILURE,		"malloc failure"},
-{ PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED,	"ctl command not implemented"},
-{ PK11_R_DATA_GREATER_THAN_MOD_LEN,	"data is bigger than mod"},
-{ PK11_R_DATA_TOO_LARGE_FOR_MODULUS,	"data is too larger for mod"},
-{ PK11_R_MISSING_KEY_COMPONENT,		"a dsa component is missing"},
-{ PK11_R_INVALID_SIGNATURE_LENGTH,	"invalid signature length"},
-{ PK11_R_INVALID_DSA_SIGNATURE_R,	"missing r in dsa verify"},
-{ PK11_R_INVALID_DSA_SIGNATURE_S,	"missing s in dsa verify"},
-{ PK11_R_INCONSISTENT_KEY,		"inconsistent key type"},
-{ PK11_R_ENCRYPTUPDATE,			"C_EncryptUpdate failed"},
-{ PK11_R_DECRYPTUPDATE,			"C_DecryptUpdate failed"},
-{ PK11_R_DIGESTINIT,			"C_DigestInit failed"},
-{ PK11_R_DIGESTUPDATE,			"C_DigestUpdate failed"},
-{ PK11_R_DIGESTFINAL,			"C_DigestFinal failed"},
-{ PK11_R_ENCRYPTFINAL,			"C_EncryptFinal failed"},
-{ PK11_R_DECRYPTFINAL,			"C_DecryptFinal failed"},
-{ PK11_R_NO_PRNG_SUPPORT,		"Slot does not support PRNG"},
-{ PK11_R_GETTOKENINFO,			"C_GetTokenInfo failed"},
-{ PK11_R_DERIVEKEY,			"C_DeriveKey failed"},
-{ PK11_R_GET_OPERATION_STATE,		"C_GetOperationState failed"},
-{ PK11_R_SET_OPERATION_STATE,		"C_SetOperationState failed"},
-{ PK11_R_INVALID_HANDLE,		"invalid PKCS#11 object handle"},
-{ PK11_R_KEY_OR_IV_LEN_PROBLEM,		"IV or key length incorrect"},
-{ PK11_R_INVALID_OPERATION_TYPE,	"invalid operation type"},
-{ PK11_R_ADD_NID_FAILED,		"failed to add NID" },
-{ PK11_R_ATFORK_FAILED,			"atfork failed" },
-{ PK11_R_TOKEN_LOGIN_FAILED,		"C_Login failed on token" },
-{ PK11_R_MORE_THAN_ONE_OBJECT_FOUND,	"more than one object found" },
-{ PK11_R_INVALID_PKCS11_URI,		"pkcs11 URI provided is invalid" },
-{ PK11_R_COULD_NOT_READ_PIN,		"could not read PIN from terminal" },
-{ PK11_R_PIN_NOT_READ_FROM_COMMAND,	"PIN not read from external command" },
-{ PK11_R_COULD_NOT_OPEN_COMMAND,	"could not popen dialog command" },
-{ PK11_R_PIPE_FAILED,			"pipe failed" },
-{ PK11_R_BAD_PASSPHRASE_SPEC,		"bad passphrasedialog specification" },
-{ PK11_R_TOKEN_NOT_INITIALIZED,		"token not initialized" },
-{ PK11_R_TOKEN_PIN_NOT_SET,		"token PIN required but not set" },
-{ PK11_R_TOKEN_PIN_NOT_PROVIDED,	"token PIN required but not provided" },
-{ PK11_R_MISSING_OBJECT_LABEL,		"missing mandatory 'object' keyword" },
-{ PK11_R_TOKEN_ATTRS_DO_NOT_MATCH,	"token attrs provided do not match" },
-{ PK11_R_PRIV_KEY_NOT_FOUND,		"private key not found in keystore" },
-{ PK11_R_NO_OBJECT_FOUND,		"specified object not found" },
-{ PK11_R_PIN_CACHING_POLICY_INVALID,	"PIN set but caching policy invalid" },
-{ PK11_R_SYSCONF_FAILED,		"sysconf failed" },
-{ PK11_R_MMAP_FAILED,			"mmap failed" },
-{ PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING,	"PROC_LOCK_MEMORY privilege missing" },
-{ PK11_R_MLOCK_FAILED,			"mlock failed" },
-{ PK11_R_FORK_FAILED,			"fork failed" },
-{ 0,	NULL}
-};
-#endif	/* OPENSSL_NO_ERR */
-
-static int pk11_lib_error_code = 0;
-static int pk11_error_init = 1;
-
-#ifdef PK11_ENGINE_LIB_NAME
-static ERR_STRING_DATA pk11_engine_lib_name[] =
-{
-{0, PK11_ENGINE_LIB_NAME},
-{0, NULL}
-};
-#endif
-
-static void
-ERR_load_pk11_strings(void)
-	{
-	if (pk11_lib_error_code == 0)
-		pk11_lib_error_code = ERR_get_next_error_library();
-
-	if (pk11_error_init)
-		{
-		pk11_error_init = 0;
-#ifndef OPENSSL_NO_ERR
-		ERR_load_strings(pk11_lib_error_code, pk11_str_functs);
-		ERR_load_strings(pk11_lib_error_code, pk11_str_reasons);
-#endif
-
-#ifdef PK11_ENGINE_LIB_NAME
-		pk11_engine_lib_name->error =
-		    ERR_PACK(pk11_lib_error_code, 0, 0);
-		ERR_load_strings(0, pk11_engine_lib_name);
-#endif
-		}
-}
-
-static void
-ERR_unload_pk11_strings(void)
-	{
-	if (pk11_error_init == 0)
-		{
-#ifndef OPENSSL_NO_ERR
-		ERR_unload_strings(pk11_lib_error_code, pk11_str_functs);
-		ERR_unload_strings(pk11_lib_error_code, pk11_str_reasons);
-#endif
-
-#ifdef PK11_ENGINE_LIB_NAME
-		ERR_unload_strings(0, pk11_engine_lib_name);
-#endif
-
-		pk11_error_init = 1;
-		}
-}
-
-void
-ERR_pk11_error(int function, int reason, char *file, int line)
-{
-	if (pk11_lib_error_code == 0)
-		pk11_lib_error_code = ERR_get_next_error_library();
-	ERR_PUT_error(pk11_lib_error_code, function, reason, file, line);
-}
-
-void
-PK11err_add_data(int function, int reason, CK_RV rv)
-{
-	char tmp_buf[20];
-
-	PK11err(function, reason);
-	(void) snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-	ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-}
--- a/components/openssl/openssl-0.9.8-fips-140/engines/pkcs11/e_pk11_err.h	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- *
- */
-
-/*
- * This product includes software developed by the OpenSSL Project for
- * use in the OpenSSL Toolkit (http://www.openssl.org/).
- *
- * This project also referenced hw_pkcs11-0.9.7b.patch written by
- * Afchine Madjlessi.
- */
-/*
- * ====================================================================
- * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    [email protected]
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
-#ifndef	E_PK11_ERR_H
-#define	E_PK11_ERR_H
-
-void ERR_pk11_error(int function, int reason, char *file, int line);
-void PK11err_add_data(int function, int reason, CK_RV rv);
-#define	PK11err(f, r)	ERR_pk11_error((f), (r), __FILE__, __LINE__)
-
-/* Error codes for the PK11 functions. */
-
-/* Function codes. */
-
-#define	PK11_F_INIT 				100
-#define	PK11_F_FINISH				101
-#define	PK11_F_DESTROY 				102
-#define	PK11_F_CTRL 				103
-#define	PK11_F_RSA_INIT 			104
-#define	PK11_F_RSA_FINISH 			105
-#define	PK11_F_GET_PUB_RSA_KEY 			106
-#define	PK11_F_GET_PRIV_RSA_KEY 		107
-#define	PK11_F_RSA_GEN_KEY 			108
-#define	PK11_F_RSA_PUB_ENC 			109
-#define	PK11_F_RSA_PRIV_ENC 			110
-#define	PK11_F_RSA_PUB_DEC 			111
-#define	PK11_F_RSA_PRIV_DEC 			112
-#define	PK11_F_RSA_SIGN 			113
-#define	PK11_F_RSA_VERIFY 			114
-#define	PK11_F_RAND_ADD 			115
-#define	PK11_F_RAND_BYTES 			116
-#define	PK11_F_GET_SESSION 			117
-#define	PK11_F_FREE_SESSION 			118
-#define	PK11_F_LOAD_PUBKEY 			119
-#define	PK11_F_LOAD_PRIVKEY 			120
-#define	PK11_F_RSA_PUB_ENC_LOW 			121
-#define	PK11_F_RSA_PRIV_ENC_LOW 		122
-#define	PK11_F_RSA_PUB_DEC_LOW 			123
-#define	PK11_F_RSA_PRIV_DEC_LOW 		124
-#define	PK11_F_DSA_SIGN				125
-#define	PK11_F_DSA_VERIFY			126
-#define	PK11_F_DSA_INIT				127
-#define	PK11_F_DSA_FINISH			128
-#define	PK11_F_GET_PUB_DSA_KEY			129
-#define	PK11_F_GET_PRIV_DSA_KEY 		130
-#define	PK11_F_DH_INIT 				131
-#define	PK11_F_DH_FINISH 			132
-#define	PK11_F_MOD_EXP_DH 			133
-#define	PK11_F_GET_DH_KEY 			134
-#define	PK11_F_FREE_ALL_SESSIONS		135
-#define	PK11_F_SETUP_SESSION			136
-#define	PK11_F_DESTROY_OBJECT			137
-#define	PK11_F_CIPHER_INIT			138
-#define	PK11_F_CIPHER_DO_CIPHER			139
-#define	PK11_F_GET_CIPHER_KEY			140
-#define	PK11_F_DIGEST_INIT			141
-#define	PK11_F_DIGEST_UPDATE			142
-#define	PK11_F_DIGEST_FINAL			143
-#define	PK11_F_CHOOSE_SLOT			144
-#define	PK11_F_CIPHER_FINAL			145
-#define	PK11_F_LIBRARY_INIT 			146
-#define	PK11_F_LOAD 				147
-#define	PK11_F_DH_GEN_KEY			148
-#define	PK11_F_DH_COMP_KEY 			149
-#define	PK11_F_DIGEST_COPY 			150
-#define	PK11_F_CIPHER_CLEANUP			151
-#define	PK11_F_ACTIVE_ADD			152
-#define	PK11_F_ACTIVE_DELETE			153
-#define	PK11_F_CHECK_HW_MECHANISMS		154
-#define	PK11_F_INIT_SYMMETRIC			155
-#define	PK11_F_ADD_AES_CTR_NIDS			156
-#define	PK11_F_INIT_ALL_LOCKS			157
-#define	PK11_F_RETURN_SESSION			158
-#define	PK11_F_GET_PIN				159
-#define	PK11_F_FIND_ONE_OBJECT 			160
-#define	PK11_F_CHECK_TOKEN_ATTRS 		161
-#define	PK11_F_CACHE_PIN			162
-#define	PK11_F_MLOCK_PIN_IN_MEMORY		163
-#define	PK11_F_TOKEN_LOGIN 			164
-#define	PK11_F_TOKEN_RELOGIN 			165
-#define	PK11_F_RUN_ASKPASS 			166
-
-/* Reason codes. */
-#define	PK11_R_ALREADY_LOADED 			100
-#define	PK11_R_DSO_FAILURE 			101
-#define	PK11_R_NOT_LOADED 			102
-#define	PK11_R_PASSED_NULL_PARAMETER 		103
-#define	PK11_R_COMMAND_NOT_IMPLEMENTED 		104
-#define	PK11_R_INITIALIZE 			105
-#define	PK11_R_FINALIZE 			106
-#define	PK11_R_GETINFO 				107
-#define	PK11_R_GETSLOTLIST 			108
-#define	PK11_R_NO_MODULUS_OR_NO_EXPONENT 	109
-#define	PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID 	110
-#define	PK11_R_GETATTRIBUTVALUE 		111
-#define	PK11_R_NO_MODULUS 			112
-#define	PK11_R_NO_EXPONENT 			113
-#define	PK11_R_FINDOBJECTSINIT 			114
-#define	PK11_R_FINDOBJECTS 			115
-#define	PK11_R_FINDOBJECTSFINAL 		116
-#define	PK11_R_CREATEOBJECT 			118
-#define	PK11_R_DESTROYOBJECT 			119
-#define	PK11_R_OPENSESSION 			120
-#define	PK11_R_CLOSESESSION 			121
-#define	PK11_R_ENCRYPTINIT 			122
-#define	PK11_R_ENCRYPT 				123
-#define	PK11_R_SIGNINIT 			124
-#define	PK11_R_SIGN 				125
-#define	PK11_R_DECRYPTINIT 			126
-#define	PK11_R_DECRYPT 				127
-#define	PK11_R_VERIFYINIT 			128
-#define	PK11_R_VERIFY 				129
-#define	PK11_R_VERIFYRECOVERINIT 		130
-#define	PK11_R_VERIFYRECOVER 			131
-#define	PK11_R_GEN_KEY 				132
-#define	PK11_R_SEEDRANDOM 			133
-#define	PK11_R_GENERATERANDOM 			134
-#define	PK11_R_INVALID_MESSAGE_LENGTH 		135
-#define	PK11_R_UNKNOWN_ALGORITHM_TYPE 		136
-#define	PK11_R_UNKNOWN_ASN1_OBJECT_ID 		137
-#define	PK11_R_UNKNOWN_PADDING_TYPE 		138
-#define	PK11_R_PADDING_CHECK_FAILED 		139
-#define	PK11_R_DIGEST_TOO_BIG 			140
-#define	PK11_R_MALLOC_FAILURE 			141
-#define	PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED 	142
-#define	PK11_R_DATA_GREATER_THAN_MOD_LEN 	143
-#define	PK11_R_DATA_TOO_LARGE_FOR_MODULUS 	144
-#define	PK11_R_MISSING_KEY_COMPONENT		145
-#define	PK11_R_INVALID_SIGNATURE_LENGTH		146
-#define	PK11_R_INVALID_DSA_SIGNATURE_R		147
-#define	PK11_R_INVALID_DSA_SIGNATURE_S		148
-#define	PK11_R_INCONSISTENT_KEY			149
-#define	PK11_R_ENCRYPTUPDATE			150
-#define	PK11_R_DECRYPTUPDATE			151
-#define	PK11_R_DIGESTINIT			152
-#define	PK11_R_DIGESTUPDATE			153
-#define	PK11_R_DIGESTFINAL			154
-#define	PK11_R_ENCRYPTFINAL			155
-#define	PK11_R_DECRYPTFINAL			156
-#define	PK11_R_NO_PRNG_SUPPORT			157
-#define	PK11_R_GETTOKENINFO			158
-#define	PK11_R_DERIVEKEY			159
-#define	PK11_R_GET_OPERATION_STATE		160
-#define	PK11_R_SET_OPERATION_STATE		161
-#define	PK11_R_INVALID_HANDLE			162
-#define	PK11_R_KEY_OR_IV_LEN_PROBLEM		163
-#define	PK11_R_INVALID_OPERATION_TYPE		164
-#define	PK11_R_ADD_NID_FAILED			165
-#define	PK11_R_ATFORK_FAILED			166
-#define	PK11_R_TOKEN_LOGIN_FAILED		167
-#define	PK11_R_MORE_THAN_ONE_OBJECT_FOUND	168
-#define	PK11_R_INVALID_PKCS11_URI		169
-#define	PK11_R_COULD_NOT_READ_PIN		170
-#define	PK11_R_COULD_NOT_OPEN_COMMAND		171
-#define	PK11_R_PIPE_FAILED			172
-#define	PK11_R_PIN_NOT_READ_FROM_COMMAND	173
-#define	PK11_R_BAD_PASSPHRASE_SPEC		174
-#define	PK11_R_TOKEN_NOT_INITIALIZED		175
-#define	PK11_R_TOKEN_PIN_NOT_SET		176
-#define	PK11_R_TOKEN_PIN_NOT_PROVIDED		177
-#define	PK11_R_MISSING_OBJECT_LABEL		178
-#define	PK11_R_TOKEN_ATTRS_DO_NOT_MATCH		179
-#define	PK11_R_PRIV_KEY_NOT_FOUND		180
-#define	PK11_R_NO_OBJECT_FOUND			181
-#define	PK11_R_PIN_CACHING_POLICY_INVALID	182
-#define	PK11_R_SYSCONF_FAILED			183
-#define	PK11_R_MMAP_FAILED			183
-#define	PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING	184
-#define	PK11_R_MLOCK_FAILED			185
-#define	PK11_R_FORK_FAILED			186
-
-#endif /* E_PK11_ERR_H */
--- a/components/openssl/openssl-0.9.8-fips-140/engines/pkcs11/e_pk11_pub.c	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3235 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- *
- */
-
-/* crypto/engine/e_pk11_pub.c */
-/*
- * This product includes software developed by the OpenSSL Project for
- * use in the OpenSSL Toolkit (http://www.openssl.org/).
- *
- * This project also referenced hw_pkcs11-0.9.7b.patch written by
- * Afchine Madjlessi.
- */
-/*
- * ====================================================================
- * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    [email protected]
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <strings.h>
-
-#include <openssl/e_os2.h>
-#include <openssl/crypto.h>
-#include <openssl/engine.h>
-#include <openssl/dso.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-#include <openssl/pem.h>
-#ifndef OPENSSL_NO_RSA
-#include <openssl/rsa.h>
-#endif /* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-#include <openssl/dsa.h>
-#endif /* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-#include <openssl/dh.h>
-#endif /* OPENSSL_NO_DH */
-#include <openssl/rand.h>
-#include <openssl/objects.h>
-#include <openssl/x509.h>
-#include <pthread.h>
-#include <libgen.h>
-
-#ifndef OPENSSL_NO_HW
-#ifndef OPENSSL_NO_HW_PK11
-
-#include <security/cryptoki.h>
-#include <security/pkcs11.h>
-#include "e_pk11.h"
-#include "e_pk11_uri.h"
-
-static CK_BBOOL pk11_login_done = CK_FALSE;
-extern CK_SLOT_ID pubkey_SLOTID;
-
-/*
- * During the reinitialization after a detected fork we will try to login to the
- * token using the passphrasedialog keyword that we inherit from the parent.
- */
-char *passphrasedialog;
-
-#ifndef OPENSSL_NO_RSA
-/* RSA stuff */
-static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding);
-static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding);
-static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding);
-static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding);
-static int pk11_RSA_init(RSA *rsa);
-static int pk11_RSA_finish(RSA *rsa);
-static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
-	unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
-static int pk11_RSA_verify(int dtype, const unsigned char *m,
-	unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
-	const RSA *rsa);
-EVP_PKEY *pk11_load_privkey(ENGINE*, const char *privkey_id,
-	UI_METHOD *ui_method, void *callback_data);
-EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_id,
-	UI_METHOD *ui_method, void *callback_data);
-
-static int pk11_RSA_public_encrypt_low(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa);
-static int pk11_RSA_private_encrypt_low(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa);
-static int pk11_RSA_public_decrypt_low(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa);
-static int pk11_RSA_private_decrypt_low(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa);
-
-static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, PK11_SESSION *sp);
-static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, PK11_SESSION *sp);
-
-static int pk11_check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
-static int pk11_check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
-#endif
-
-/* DSA stuff */
-#ifndef OPENSSL_NO_DSA
-static int pk11_DSA_init(DSA *dsa);
-static int pk11_DSA_finish(DSA *dsa);
-static DSA_SIG *pk11_dsa_do_sign(const unsigned char *dgst, int dlen,
-	DSA *dsa);
-static int pk11_dsa_do_verify(const unsigned char *dgst, int dgst_len,
-	DSA_SIG *sig, DSA *dsa);
-
-static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, DSA **key_ptr,
-	BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session);
-static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, DSA **key_ptr,
-	BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session);
-
-static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa);
-static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa);
-#endif
-
-/* DH stuff */
-#ifndef OPENSSL_NO_DH
-static int pk11_DH_init(DH *dh);
-static int pk11_DH_finish(DH *dh);
-static int pk11_DH_generate_key(DH *dh);
-static int pk11_DH_compute_key(unsigned char *key,
-	const BIGNUM *pub_key, DH *dh);
-
-static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, DH **key_ptr,
-	BIGNUM **priv_key, CK_SESSION_HANDLE session);
-
-static int check_new_dh_key(PK11_SESSION *sp, DH *dh);
-#endif
-
-static int find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
-	CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey);
-static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
-	CK_ULONG *ulValueLen);
-static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
-
-/* Read mode string to be used for fopen() */
-#if SOLARIS_OPENSSL
-static char *read_mode_flags = "rF";
-#else
-static char *read_mode_flags = "r";
-#endif
-
-/*
- * Increment existing or create a new reference for an asymmetric key PKCS#11
- * object handle in the active object list. If the operation fails, unlock (if
- * locked), set error variable and jump to the specified label. We use this list
- * so that we can track how many references to the PKCS#11 objects are used from
- * all our sessions structures. If we are replacing an object reference in the
- * session structure and the ref count for the reference being replaced gets to
- * 0 we know that we can safely free the object itself via C_ObjectDestroy().
- * See also TRY_OBJ_DESTROY.
- */
-#define	KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)	\
-	{								\
-	if (pk11_active_add(key_handle, alg_type) < 0)			\
-		{							\
-		var = CK_TRUE;						\
-		if (unlock)						\
-			UNLOCK_OBJSTORE(alg_type);			\
-		goto label;						\
-		}							\
-	}
-
-/*
- * Find active list entry according to object handle and return pointer to the
- * entry otherwise return NULL.
- *
- * This function presumes it is called with lock protecting the active list
- * held.
- */
-static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
-	{
-	PK11_active *entry;
-
-	for (entry = active_list[type]; entry != NULL; entry = entry->next)
-		if (entry->h == h)
-			return (entry);
-
-	return (NULL);
-	}
-
-/*
- * Search for an entry in the active list using PKCS#11 object handle as a
- * search key and return refcnt of the found/created entry or -1 in case of
- * failure.
- *
- * This function presumes it is called with lock protecting the active list
- * held.
- */
-int
-pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
-	{
-	PK11_active *entry = NULL;
-
-	if (h == CK_INVALID_HANDLE)
-		{
-		PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
-		return (-1);
-		}
-
-	/* search for entry in the active list */
-	if ((entry = pk11_active_find(h, type)) != NULL)
-		entry->refcnt++;
-	else
-		{
-		/* not found, create new entry and add it to the list */
-		entry = OPENSSL_malloc(sizeof (PK11_active));
-		if (entry == NULL)
-			{
-			PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
-			return (-1);
-			}
-		entry->h = h;
-		entry->refcnt = 1;
-		entry->prev = NULL;
-		entry->next = NULL;
-		/* connect the newly created entry to the list */
-		if (active_list[type] == NULL)
-			active_list[type] = entry;
-		else /* make the entry first in the list */
-			{
-			entry->next = active_list[type];
-			active_list[type]->prev = entry;
-			active_list[type] = entry;
-			}
-		}
-
-	return (entry->refcnt);
-	}
-
-/*
- * Remove active list entry from the list and free it.
- *
- * This function presumes it is called with lock protecting the active list
- * held.
- */
-void
-pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
-	{
-	PK11_active *prev_entry;
-
-	/* remove the entry from the list and free it */
-	if ((prev_entry = entry->prev) != NULL)
-		{
-		prev_entry->next = entry->next;
-		if (entry->next != NULL)
-			entry->next->prev = prev_entry;
-		}
-	else
-		{
-		active_list[type] = entry->next;
-		/* we were the first but not the only one */
-		if (entry->next != NULL)
-			entry->next->prev = NULL;
-		}
-
-	/* sanitization */
-	entry->h = CK_INVALID_HANDLE;
-	entry->prev = NULL;
-	entry->next = NULL;
-	OPENSSL_free(entry);
-	}
-
-/* Free all entries from the active list. */
-void
-pk11_free_active_list(PK11_OPTYPE type)
-	{
-	PK11_active *entry;
-
-	/* only for asymmetric types since only they have C_Find* locks. */
-	switch (type)
-		{
-		case OP_RSA:
-		case OP_DSA:
-		case OP_DH:
-			break;
-		default:
-			return;
-		}
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(type);
-	while ((entry = active_list[type]) != NULL)
-		pk11_active_remove(entry, type);
-	UNLOCK_OBJSTORE(type);
-	}
-
-/*
- * Search for active list entry associated with given PKCS#11 object handle,
- * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
- *
- * Return 1 if the PKCS#11 object associated with the entry has no references,
- * return 0 if there is at least one reference, -1 on error.
- *
- * This function presumes it is called with lock protecting the active list
- * held.
- */
-int
-pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
-	{
-	PK11_active *entry = NULL;
-
-	if ((entry = pk11_active_find(h, type)) == NULL)
-		{
-		PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
-		return (-1);
-		}
-
-	OPENSSL_assert(entry->refcnt > 0);
-	entry->refcnt--;
-	if (entry->refcnt == 0)
-		{
-		pk11_active_remove(entry, type);
-		return (1);
-		}
-
-	return (0);
-	}
-
-#ifndef OPENSSL_NO_RSA
-/* Our internal RSA_METHOD that we provide pointers to */
-static RSA_METHOD pk11_rsa =
-	{
-	"PKCS#11 RSA method",
-	pk11_RSA_public_encrypt,		/* rsa_pub_encrypt */
-	pk11_RSA_public_decrypt,		/* rsa_pub_decrypt */
-	pk11_RSA_private_encrypt,		/* rsa_priv_encrypt */
-	pk11_RSA_private_decrypt,		/* rsa_priv_decrypt */
-	NULL,					/* rsa_mod_exp */
-	NULL,					/* bn_mod_exp */
-	pk11_RSA_init,				/* init */
-	pk11_RSA_finish,			/* finish */
-	RSA_FLAG_SIGN_VER,			/* flags */
-	NULL,					/* app_data */
-	pk11_RSA_sign,				/* rsa_sign */
-	pk11_RSA_verify				/* rsa_verify */
-	};
-
-RSA_METHOD *
-PK11_RSA(void)
-	{
-	return (&pk11_rsa);
-	}
-#endif
-
-#ifndef OPENSSL_NO_DSA
-/* Our internal DSA_METHOD that we provide pointers to */
-static DSA_METHOD pk11_dsa =
-	{
-	"PKCS#11 DSA method",
-	pk11_dsa_do_sign, 	/* dsa_do_sign */
-	NULL, 			/* dsa_sign_setup */
-	pk11_dsa_do_verify, 	/* dsa_do_verify */
-	NULL,			/* dsa_mod_exp */
-	NULL, 			/* bn_mod_exp */
-	pk11_DSA_init, 		/* init */
-	pk11_DSA_finish, 	/* finish */
-	0, 			/* flags */
-	NULL 			/* app_data */
-	};
-
-DSA_METHOD *
-PK11_DSA(void)
-	{
-	return (&pk11_dsa);
-	}
-#endif
-
-#ifndef OPENSSL_NO_DH
-/*
- * PKCS #11 V2.20, section 11.2 specifies that the number of bytes needed for
- * output buffer may somewhat exceed the precise number of bytes needed, but
- * should not exceed it by a large amount. That may be caused, for example, by
- * rounding it up to multiple of X in the underlying bignum library. 8 should be
- * enough.
- */
-#define	DH_BUF_RESERVE	8
-
-/* Our internal DH_METHOD that we provide pointers to */
-static DH_METHOD pk11_dh =
-	{
-	"PKCS#11 DH method",
-	pk11_DH_generate_key,	/* generate_key */
-	pk11_DH_compute_key,	/* compute_key */
-	NULL,			/* bn_mod_exp */
-	pk11_DH_init,		/* init */
-	pk11_DH_finish,		/* finish */
-	0,			/* flags */
-	NULL,			/* app_data */
-	NULL			/* generate_params */
-	};
-
-DH_METHOD *
-PK11_DH(void)
-	{
-	return (&pk11_dh);
-	}
-#endif
-
-/* Size of an SSL signature: MD5+SHA1 */
-#define	SSL_SIG_LENGTH		36
-
-/* Lengths of DSA data and signature */
-#define	DSA_DATA_LEN		20
-#define	DSA_SIGNATURE_LEN	40
-
-#ifndef OPENSSL_NO_RSA
-/*
- * Similiar to OpenSSL to take advantage of the paddings. The goal is to
- * support all paddings in this engine although PK11 library does not
- * support all the paddings used in OpenSSL.
- * The input errors should have been checked in the padding functions.
- */
-static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
-		unsigned char *to, RSA *rsa, int padding)
-	{
-	int i, num = 0, r = -1;
-	unsigned char *buf = NULL;
-
-	num = BN_num_bytes(rsa->n);
-	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
-		{
-		PK11err(PK11_F_RSA_PUB_ENC, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	switch (padding)
-		{
-	case RSA_PKCS1_PADDING:
-		i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen);
-		break;
-#ifndef OPENSSL_NO_SHA
-	case RSA_PKCS1_OAEP_PADDING:
-		i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0);
-		break;
-#endif
-	case RSA_SSLV23_PADDING:
-		i = RSA_padding_add_SSLv23(buf, num, from, flen);
-		break;
-	case RSA_NO_PADDING:
-		i = RSA_padding_add_none(buf, num, from, flen);
-		break;
-	default:
-		PK11err(PK11_F_RSA_PUB_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
-		goto err;
-		}
-	if (i <= 0) goto err;
-
-	/* PK11 functions are called here */
-	r = pk11_RSA_public_encrypt_low(num, buf, to, rsa);
-err:
-	if (buf != NULL)
-		{
-		OPENSSL_cleanse(buf, num);
-		OPENSSL_free(buf);
-		}
-	return (r);
-	}
-
-
-/*
- * Similar to Openssl to take advantage of the paddings. The input errors
- * should be catched in the padding functions
- */
-static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding)
-	{
-	int i, num = 0, r = -1;
-	unsigned char *buf = NULL;
-
-	num = BN_num_bytes(rsa->n);
-	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
-		{
-		PK11err(PK11_F_RSA_PRIV_ENC, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	switch (padding)
-		{
-	case RSA_PKCS1_PADDING:
-		i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen);
-		break;
-	case RSA_NO_PADDING:
-		i = RSA_padding_add_none(buf, num, from, flen);
-		break;
-	case RSA_SSLV23_PADDING:
-	default:
-		PK11err(PK11_F_RSA_PRIV_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
-		goto err;
-		}
-	if (i <= 0) goto err;
-
-	/* PK11 functions are called here */
-	r = pk11_RSA_private_encrypt_low(num, buf, to, rsa);
-err:
-	if (buf != NULL)
-		{
-		OPENSSL_cleanse(buf, num);
-		OPENSSL_free(buf);
-		}
-	return (r);
-	}
-
-/* Similar to OpenSSL code. Input errors are also checked here */
-static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding)
-	{
-	BIGNUM f;
-	int j, num = 0, r = -1;
-	unsigned char *p;
-	unsigned char *buf = NULL;
-
-	BN_init(&f);
-
-	num = BN_num_bytes(rsa->n);
-
-	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
-		{
-		PK11err(PK11_F_RSA_PRIV_DEC, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	/*
-	 * This check was for equality but PGP does evil things
-	 * and chops off the top '0' bytes
-	 */
-	if (flen > num)
-		{
-		PK11err(PK11_F_RSA_PRIV_DEC,
-			PK11_R_DATA_GREATER_THAN_MOD_LEN);
-		goto err;
-		}
-
-	/* make data into a big number */
-	if (BN_bin2bn(from, (int)flen, &f) == NULL)
-		goto err;
-
-	if (BN_ucmp(&f, rsa->n) >= 0)
-		{
-		PK11err(PK11_F_RSA_PRIV_DEC,
-			PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
-		goto err;
-		}
-
-	/* PK11 functions are called here */
-	r = pk11_RSA_private_decrypt_low(flen, from, buf, rsa);
-
-	/*
-	 * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
-	 * Needs to skip these 0's paddings here.
-	 */
-	for (j = 0; j < r; j++)
-		if (buf[j] != 0)
-			break;
-
-	p = buf + j;
-	j = r - j;  /* j is only used with no-padding mode */
-
-	switch (padding)
-		{
-	case RSA_PKCS1_PADDING:
-		r = RSA_padding_check_PKCS1_type_2(to, num, p, j, num);
-		break;
-#ifndef OPENSSL_NO_SHA
-	case RSA_PKCS1_OAEP_PADDING:
-		r = RSA_padding_check_PKCS1_OAEP(to, num, p, j, num, NULL, 0);
-		break;
-#endif
-	case RSA_SSLV23_PADDING:
-		r = RSA_padding_check_SSLv23(to, num, p, j, num);
-		break;
-	case RSA_NO_PADDING:
-		r = RSA_padding_check_none(to, num, p, j, num);
-		break;
-	default:
-		PK11err(PK11_F_RSA_PRIV_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
-		goto err;
-		}
-	if (r < 0)
-		PK11err(PK11_F_RSA_PRIV_DEC, PK11_R_PADDING_CHECK_FAILED);
-
-err:
-	BN_clear_free(&f);
-	if (buf != NULL)
-		{
-		OPENSSL_cleanse(buf, num);
-		OPENSSL_free(buf);
-		}
-	return (r);
-	}
-
-/* Similar to OpenSSL code. Input errors are also checked here */
-static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding)
-	{
-	BIGNUM f;
-	int i, num = 0, r = -1;
-	unsigned char *p;
-	unsigned char *buf = NULL;
-
-	BN_init(&f);
-	num = BN_num_bytes(rsa->n);
-	buf = (unsigned char *)OPENSSL_malloc(num);
-	if (buf == NULL)
-		{
-		PK11err(PK11_F_RSA_PUB_DEC, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	/*
-	 * This check was for equality but PGP does evil things
-	 * and chops off the top '0' bytes
-	 */
-	if (flen > num)
-		{
-		PK11err(PK11_F_RSA_PUB_DEC, PK11_R_DATA_GREATER_THAN_MOD_LEN);
-		goto err;
-		}
-
-	if (BN_bin2bn(from, flen, &f) == NULL)
-		goto err;
-
-	if (BN_ucmp(&f, rsa->n) >= 0)
-		{
-		PK11err(PK11_F_RSA_PUB_DEC,
-			PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
-		goto err;
-		}
-
-	/* PK11 functions are called here */
-	r = pk11_RSA_public_decrypt_low(flen, from, buf, rsa);
-
-	/*
-	 * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
-	 * Needs to skip these 0's here
-	 */
-	for (i = 0; i < r; i++)
-		if (buf[i] != 0)
-			break;
-
-	p = buf + i;
-	i = r - i;  /* i is only used with no-padding mode */
-
-	switch (padding)
-		{
-	case RSA_PKCS1_PADDING:
-		r = RSA_padding_check_PKCS1_type_1(to, num, p, i, num);
-		break;
-	case RSA_NO_PADDING:
-		r = RSA_padding_check_none(to, num, p, i, num);
-		break;
-	default:
-		PK11err(PK11_F_RSA_PUB_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
-		goto err;
-		}
-	if (r < 0)
-		PK11err(PK11_F_RSA_PUB_DEC, PK11_R_PADDING_CHECK_FAILED);
-
-err:
-	BN_clear_free(&f);
-	if (buf != NULL)
-		{
-		OPENSSL_cleanse(buf, num);
-		OPENSSL_free(buf);
-		}
-	return (r);
-	}
-
-/*
- * This function implements RSA public encryption using C_EncryptInit and
- * C_Encrypt pk11 interfaces. Note that the CKM_RSA_X_509 is used here.
- * The calling function allocated sufficient memory in "to" to store results.
- */
-static int pk11_RSA_public_encrypt_low(int flen,
-	const unsigned char *from, unsigned char *to, RSA *rsa)
-	{
-	CK_ULONG bytes_encrypted = flen;
-	int retval = -1;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (-1);
-
-	(void) pk11_check_new_rsa_key_pub(sp, rsa);
-
-	h_pub_key = sp->opdata_rsa_pub_key;
-	if (h_pub_key == CK_INVALID_HANDLE)
-		h_pub_key = sp->opdata_rsa_pub_key =
-			pk11_get_public_rsa_key(rsa, sp);
-
-	if (h_pub_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_EncryptInit(sp->session, p_mech,
-			h_pub_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
-			    PK11_R_ENCRYPTINIT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-
-		rv = pFuncList->C_Encrypt(sp->session,
-			(unsigned char *)from, flen, to, &bytes_encrypted);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
-			    PK11_R_ENCRYPT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-		retval = bytes_encrypted;
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (retval);
-	}
-
-
-/*
- * This function implements RSA private encryption using C_SignInit and
- * C_Sign pk11 APIs. Note that CKM_RSA_X_509 is used here.
- * The calling function allocated sufficient memory in "to" to store results.
- */
-static int pk11_RSA_private_encrypt_low(int flen,
-	const unsigned char *from, unsigned char *to, RSA *rsa)
-	{
-	CK_ULONG ul_sig_len = flen;
-	int retval = -1;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (-1);
-
-	(void) pk11_check_new_rsa_key_priv(sp, rsa);
-
-	h_priv_key = sp->opdata_rsa_priv_key;
-	if (h_priv_key == CK_INVALID_HANDLE)
-		h_priv_key = sp->opdata_rsa_priv_key =
-			pk11_get_private_rsa_key(rsa, sp);
-
-	if (h_priv_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_SignInit(sp->session, p_mech,
-			h_priv_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW,
-			    PK11_R_SIGNINIT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-
-		rv = pFuncList->C_Sign(sp->session,
-			(unsigned char *)from, flen, to, &ul_sig_len);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGN,
-			    rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-
-		retval = ul_sig_len;
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (retval);
-	}
-
-
-/*
- * This function implements RSA private decryption using C_DecryptInit and
- * C_Decrypt pk11 APIs. Note that CKM_RSA_X_509 mechanism is used here.
- * The calling function allocated sufficient memory in "to" to store results.
- */
-static int pk11_RSA_private_decrypt_low(int flen,
-	const unsigned char *from, unsigned char *to, RSA *rsa)
-	{
-	CK_ULONG bytes_decrypted = flen;
-	int retval = -1;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_priv_key;
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (-1);
-
-	(void) pk11_check_new_rsa_key_priv(sp, rsa);
-
-	h_priv_key = sp->opdata_rsa_priv_key;
-	if (h_priv_key == CK_INVALID_HANDLE)
-		h_priv_key = sp->opdata_rsa_priv_key =
-			pk11_get_private_rsa_key(rsa, sp);
-
-	if (h_priv_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_DecryptInit(sp->session, p_mech,
-			h_priv_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
-				PK11_R_DECRYPTINIT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-
-		rv = pFuncList->C_Decrypt(sp->session,
-			(unsigned char *)from, flen, to, &bytes_decrypted);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
-			    PK11_R_DECRYPT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-		retval = bytes_decrypted;
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (retval);
-	}
-
-
-/*
- * This function implements RSA public decryption using C_VerifyRecoverInit
- * and C_VerifyRecover pk11 APIs. Note that CKM_RSA_X_509 is used here.
- * The calling function allocated sufficient memory in "to" to store results.
- */
-static int pk11_RSA_public_decrypt_low(int flen,
-	const unsigned char *from, unsigned char *to, RSA *rsa)
-	{
-	CK_ULONG bytes_decrypted = flen;
-	int retval = -1;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (-1);
-
-	(void) pk11_check_new_rsa_key_pub(sp, rsa);
-
-	h_pub_key = sp->opdata_rsa_pub_key;
-	if (h_pub_key == CK_INVALID_HANDLE)
-		h_pub_key = sp->opdata_rsa_pub_key =
-			pk11_get_public_rsa_key(rsa, sp);
-
-	if (h_pub_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_VerifyRecoverInit(sp->session,
-			p_mech, h_pub_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
-				PK11_R_VERIFYRECOVERINIT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-
-		rv = pFuncList->C_VerifyRecover(sp->session,
-			(unsigned char *)from, flen, to, &bytes_decrypted);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
-			    PK11_R_VERIFYRECOVER, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-		retval = bytes_decrypted;
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (retval);
-	}
-
-static int pk11_RSA_init(RSA *rsa)
-	{
-	/*
-	 * This flag in the RSA_METHOD enables the new rsa_sign,
-	 * rsa_verify functions. See rsa.h for details.
-	 */
-	rsa->flags |= RSA_FLAG_SIGN_VER;
-
-	return (1);
-	}
-
-static int pk11_RSA_finish(RSA *rsa)
-	{
-	/*
-	 * Since we are overloading OpenSSL's native RSA_eay_finish() we need
-	 * to do the same as in the original function, i.e. to free bignum
-	 * structures.
-	 */
-	if (rsa->_method_mod_n != NULL)
-		BN_MONT_CTX_free(rsa->_method_mod_n);
-	if (rsa->_method_mod_p != NULL)
-		BN_MONT_CTX_free(rsa->_method_mod_p);
-	if (rsa->_method_mod_q != NULL)
-		BN_MONT_CTX_free(rsa->_method_mod_q);
-
-	return (1);
-	}
-
-/*
- * Standard engine interface function. Majority codes here are from
- * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
- * See more details in rsa/rsa_sign.c
- */
-static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
-	unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
-	{
-	X509_SIG sig;
-	ASN1_TYPE parameter;
-	int i, j;
-	unsigned char *p, *s = NULL;
-	X509_ALGOR algor;
-	ASN1_OCTET_STRING digest;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_priv_key;
-	PK11_SESSION *sp = NULL;
-	int ret = 0;
-	unsigned long ulsiglen;
-
-	/* Encode the digest */
-	/* Special case: SSL signature, just check the length */
-	if (type == NID_md5_sha1)
-		{
-		if (m_len != SSL_SIG_LENGTH)
-			{
-			PK11err(PK11_F_RSA_SIGN,
-				PK11_R_INVALID_MESSAGE_LENGTH);
-			goto err;
-			}
-		i = SSL_SIG_LENGTH;
-		s = (unsigned char *)m;
-		}
-	else
-		{
-		sig.algor = &algor;
-		sig.algor->algorithm = OBJ_nid2obj(type);
-		if (sig.algor->algorithm == NULL)
-			{
-			PK11err(PK11_F_RSA_SIGN,
-				PK11_R_UNKNOWN_ALGORITHM_TYPE);
-			goto err;
-			}
-		if (sig.algor->algorithm->length == 0)
-			{
-			PK11err(PK11_F_RSA_SIGN,
-				PK11_R_UNKNOWN_ASN1_OBJECT_ID);
-			goto err;
-			}
-		parameter.type = V_ASN1_NULL;
-		parameter.value.ptr = NULL;
-		sig.algor->parameter = &parameter;
-
-		sig.digest = &digest;
-		sig.digest->data = (unsigned char *)m;
-		sig.digest->length = m_len;
-
-		i = i2d_X509_SIG(&sig, NULL);
-		}
-
-	j = RSA_size(rsa);
-	if ((i - RSA_PKCS1_PADDING) > j)
-		{
-		PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
-		goto err;
-		}
-
-	if (type != NID_md5_sha1)
-		{
-		s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
-		if (s == NULL)
-			{
-			PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		p = s;
-		(void) i2d_X509_SIG(&sig, &p);
-		}
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		goto err;
-
-	(void) pk11_check_new_rsa_key_priv(sp, rsa);
-
-	h_priv_key = sp->opdata_rsa_priv_key;
-	if (h_priv_key == CK_INVALID_HANDLE)
-		h_priv_key = sp->opdata_rsa_priv_key =
-			pk11_get_private_rsa_key((RSA *)rsa, sp);
-
-	if (h_priv_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
-			goto err;
-			}
-
-		ulsiglen = j;
-		rv = pFuncList->C_Sign(sp->session, s, i, sigret,
-			(CK_ULONG_PTR) &ulsiglen);
-		*siglen = ulsiglen;
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
-			goto err;
-			}
-		ret = 1;
-		}
-
-err:
-	if (type != NID_md5_sha1)
-		{
-		(void) memset(s, 0, (unsigned int)(j + 1));
-		OPENSSL_free(s);
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (ret);
-	}
-
-static int pk11_RSA_verify(int type, const unsigned char *m,
-	unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
-	const RSA *rsa)
-	{
-	X509_SIG sig;
-	ASN1_TYPE parameter;
-	int i, j;
-	unsigned char *p, *s = NULL;
-	X509_ALGOR algor;
-	ASN1_OCTET_STRING digest;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_pub_key;
-	PK11_SESSION *sp = NULL;
-	int ret = 0;
-
-	/* Encode the digest	*/
-	/* Special case: SSL signature, just check the length */
-	if (type == NID_md5_sha1)
-		{
-		if (m_len != SSL_SIG_LENGTH)
-			{
-			PK11err(PK11_F_RSA_VERIFY,
-				PK11_R_INVALID_MESSAGE_LENGTH);
-			goto err;
-			}
-		i = SSL_SIG_LENGTH;
-		s = (unsigned char *)m;
-		}
-	else
-		{
-		sig.algor = &algor;
-		sig.algor->algorithm = OBJ_nid2obj(type);
-		if (sig.algor->algorithm == NULL)
-			{
-			PK11err(PK11_F_RSA_VERIFY,
-				PK11_R_UNKNOWN_ALGORITHM_TYPE);
-			goto err;
-			}
-		if (sig.algor->algorithm->length == 0)
-			{
-			PK11err(PK11_F_RSA_VERIFY,
-				PK11_R_UNKNOWN_ASN1_OBJECT_ID);
-			goto err;
-			}
-		parameter.type = V_ASN1_NULL;
-		parameter.value.ptr = NULL;
-		sig.algor->parameter = &parameter;
-		sig.digest = &digest;
-		sig.digest->data = (unsigned char *)m;
-		sig.digest->length = m_len;
-		i = i2d_X509_SIG(&sig, NULL);
-		}
-
-	j = RSA_size(rsa);
-	if ((i - RSA_PKCS1_PADDING) > j)
-		{
-		PK11err(PK11_F_RSA_VERIFY, PK11_R_DIGEST_TOO_BIG);
-		goto err;
-		}
-
-	if (type != NID_md5_sha1)
-		{
-		s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
-		if (s == NULL)
-			{
-			PK11err(PK11_F_RSA_VERIFY, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		p = s;
-		(void) i2d_X509_SIG(&sig, &p);
-		}
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		goto err;
-
-	(void) pk11_check_new_rsa_key_pub(sp, rsa);
-
-	h_pub_key = sp->opdata_rsa_pub_key;
-	if (h_pub_key == CK_INVALID_HANDLE)
-		h_pub_key = sp->opdata_rsa_pub_key =
-			pk11_get_public_rsa_key((RSA *)rsa, sp);
-
-	if (h_pub_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_VerifyInit(sp->session, p_mech,
-			h_pub_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFYINIT,
-			    rv);
-			goto err;
-			}
-		rv = pFuncList->C_Verify(sp->session, s, i, sigbuf,
-			(CK_ULONG)siglen);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFY, rv);
-			goto err;
-			}
-		ret = 1;
-		}
-
-err:
-	if (type != NID_md5_sha1)
-		{
-		(void) memset(s, 0, (unsigned int)siglen);
-		OPENSSL_free(s);
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (ret);
-	}
-
-#define	MAXATTR	1024
-/*
- * Load RSA private key from a file or get its PKCS#11 handle if stored in the
- * PKCS#11 token.
- */
-/* ARGSUSED */
-EVP_PKEY *pk11_load_privkey(ENGINE* e, const char *privkey_id,
-	UI_METHOD *ui_method, void *callback_data)
-	{
-	EVP_PKEY *pkey = NULL;
-	FILE *privkey;
-	CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
-	RSA *rsa = NULL;
-	PK11_SESSION *sp;
-	/* Anything else below is needed for the key by reference extension. */
-	const char *file;
-	int ret;
-	pkcs11_uri uri_struct;
-	CK_RV rv;
-	CK_BBOOL is_token = CK_TRUE;
-	CK_BBOOL rollback = CK_FALSE;
-	CK_BYTE attr_data[8][MAXATTR];
-	CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
-	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
-
-	/* We look for private keys only. */
-	CK_ATTRIBUTE search_templ[] =
-		{
-		{CKA_TOKEN, &is_token, sizeof (is_token)},
-		{CKA_CLASS, &key_class, sizeof (key_class)},
-		{CKA_LABEL, NULL, 0}
-		};
-
-	/*
-	 * These public attributes are needed to initialize the OpenSSL RSA
-	 * structure with something we can use to look up the key. Note that we
-	 * never ask for private components.
-	 */
-	CK_ATTRIBUTE get_templ[] =
-		{
-		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
-		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
-		};
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (NULL);
-
-	/*
-	 * The next function will decide whether we are going to access keys in
-	 * the token or read them from plain files. It all depends on what is in
-	 * the 'privkey_id' parameter.
-	 */
-	ret = pk11_process_pkcs11_uri(privkey_id, &uri_struct, &file);
-
-	if (ret == 0)
-		goto err;
-
-	/* We will try to access a key from a PKCS#11 token. */
-	if (ret == 1)
-		{
-		if (pk11_check_token_attrs(&uri_struct) == 0)
-			goto err;
-
-		search_templ[2].pValue = uri_struct.object;
-		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
-
-		if (pk11_token_login(sp->session, &pk11_login_done,
-		    &uri_struct, CK_TRUE) == 0)
-			goto err;
-
-		/*
-		 * Now let's try to find the key in the token. It is a failure
-		 * if we can't find it.
-		 */
-		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
-		    &ks_key) == 0)
-			goto err;
-
-		/*
-		 * Free the structure now. Note that we use uri_struct's field
-		 * directly in the template so we cannot free it until the find
-		 * is done.
-		 */
-		pk11_free_pkcs11_uri(&uri_struct, 0);
-
-		/*
-		 * We might have a cache hit which we could confirm according to
-		 * the 'n'/'e' params, RSA public pointer as NULL, and non-NULL
-		 * RSA private pointer. However, it is easier just to recreate
-		 * everything. We expect the keys to be loaded once and used
-		 * many times. We do not check the return value because even in
-		 * case of failure the sp structure will have both key pointer
-		 * and object handle cleaned and pk11_destroy_object() reports
-		 * the failure to the OpenSSL error message buffer.
-		 */
-		(void) pk11_destroy_rsa_object_priv(sp, CK_TRUE);
-
-		sp->opdata_rsa_priv_key = ks_key;
-		/* This object shall not be deleted on a cache miss. */
-		sp->persistent = CK_TRUE;
-
-		if ((rsa = sp->opdata_rsa_priv = RSA_new_method(e)) == NULL)
-			goto err;
-
-		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
-		    get_templ, 2)) != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_LOAD_PRIVKEY,
-			    PK11_R_GETATTRIBUTVALUE, rv);
-			goto err;
-			}
-
-		/*
-		 * Cache the RSA private structure pointer. We do not use it now
-		 * for key-by-ref keys but let's do it for consistency reasons.
-		 */
-		sp->opdata_rsa_priv = rsa;
-
-		/*
-		 * We do not use pk11_get_private_rsa_key() here so we must take
-		 * care of handle management ourselves.
-		 */
-		KEY_HANDLE_REFHOLD(ks_key, OP_RSA, CK_FALSE, rollback, err);
-
-		/*
-		 * Those are the sensitive components we do not want to export
-		 * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
-		 */
-		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
-		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
-		/*
-		 * Must have 'n'/'e' components in the session structure as
-		 * well. They serve as a public look-up key for the private key
-		 * in the keystore.
-		 */
-		attr_to_BN(&get_templ[0], attr_data[0], &sp->opdata_rsa_n_num);
-		attr_to_BN(&get_templ[1], attr_data[1], &sp->opdata_rsa_e_num);
-
-		if ((pkey = EVP_PKEY_new()) == NULL)
-			goto err;
-
-		if (EVP_PKEY_set1_RSA(pkey, rsa) == 0)
-			goto err;
-		}
-	else
-		if ((privkey = fopen(file, read_mode_flags)) != NULL)
-			{
-			pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
-			(void) fclose(privkey);
-			if (pkey != NULL)
-				{
-				rsa = EVP_PKEY_get1_RSA(pkey);
-				if (rsa != NULL)
-					{
-					(void) pk11_check_new_rsa_key_priv(sp,
-					    rsa);
-
-					h_priv_key = sp->opdata_rsa_priv_key =
-					    pk11_get_private_rsa_key(rsa, sp);
-					if (h_priv_key == CK_INVALID_HANDLE)
-						goto err;
-					}
-				else
-					goto err;
-				}
-			}
-
-	pk11_return_session(sp, OP_RSA);
-	return (pkey);
-err:
-	if (rsa != NULL)
-		RSA_free(rsa);
-	if (pkey != NULL)
-		{
-		EVP_PKEY_free(pkey);
-		pkey = NULL;
-		}
-	return (pkey);
-	}
-
-/* Load RSA public key from a file or load it from the PKCS#11 token. */
-/* ARGSUSED */
-EVP_PKEY *pk11_load_pubkey(ENGINE* e, const char *pubkey_id,
-	UI_METHOD *ui_method, void *callback_data)
-	{
-	EVP_PKEY *pkey = NULL;
-	FILE *pubkey;
-	CK_OBJECT_HANDLE  h_pub_key = CK_INVALID_HANDLE;
-	RSA *rsa = NULL;
-	PK11_SESSION *sp;
-	/* everything else below needed for key by reference extension */
-	int ret;
-	const char *file;
-	pkcs11_uri uri_struct;
-	CK_RV rv;
-	CK_BBOOL is_token = CK_TRUE;
-	CK_BYTE attr_data[2][MAXATTR];
-	CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
-	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
-
-	CK_ATTRIBUTE search_templ[] =
-		{
-		{CKA_TOKEN, &is_token, sizeof (is_token)},
-		{CKA_CLASS, &key_class, sizeof (key_class)},
-		{CKA_LABEL, NULL, 0}
-		};
-
-	/*
-	 * These public attributes are needed to initialize OpenSSL RSA
-	 * structure with something we can use to look up the key.
-	 */
-	CK_ATTRIBUTE get_templ[] =
-		{
-		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
-		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
-		};
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (NULL);
-
-	ret = pk11_process_pkcs11_uri(pubkey_id, &uri_struct, &file);
-
-	if (ret == 0)
-		goto err;
-
-	if (ret == 1)
-		{
-		if (pk11_check_token_attrs(&uri_struct) == 0)
-			goto err;
-
-		search_templ[2].pValue = uri_struct.object;
-		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
-
-		if (pk11_token_login(sp->session, &pk11_login_done,
-		    &uri_struct, CK_FALSE) == 0)
-			goto err;
-
-		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
-		    &ks_key) == 0)
-			{
-			goto err;
-			}
-
-		/*
-		 * Free the structure now. Note that we use uri_struct's field
-		 * directly in the template so we can't free until find is done.
-		 */
-		pk11_free_pkcs11_uri(&uri_struct, 0);
-		/*
-		 * We load a new public key so we will create a new RSA
-		 * structure. No cache hit is possible.
-		 */
-		(void) pk11_destroy_rsa_object_pub(sp, CK_TRUE);
-		sp->opdata_rsa_pub_key = ks_key;
-
-		if ((rsa = sp->opdata_rsa_pub = RSA_new_method(e)) == NULL)
-			goto err;
-
-		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
-		    get_templ, 2)) != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_LOAD_PUBKEY,
-			    PK11_R_GETATTRIBUTVALUE, rv);
-			goto err;
-			}
-
-		/*
-		 * Cache the RSA public structure pointer.
-		 */
-		sp->opdata_rsa_pub = rsa;
-
-		/*
-		 * These are the sensitive components we do not want to export
-		 * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
-		 */
-		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
-		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
-
-		if ((pkey = EVP_PKEY_new()) == NULL)
-			goto err;
-
-		if (EVP_PKEY_set1_RSA(pkey, rsa) == 0)
-			goto err;
-
-		/*
-		 * Create a session object from it so that when calling
-		 * pk11_get_public_rsa_key() the next time, we can find it. The
-		 * reason why we do that is that we cannot tell from the RSA
-		 * structure (OpenSSL RSA structure does not have any room for
-		 * additional data used by the engine, for example) if it bears
-		 * a public key stored in the keystore or not so it's better if
-		 * we always have a session key. Note that this is different
-		 * from what we do for the private keystore objects but in that
-		 * case, we can tell from the RSA structure that the keystore
-		 * object is in play - the 'd' component is NULL in that case.
-		 */
-		h_pub_key = sp->opdata_rsa_pub_key =
-		    pk11_get_public_rsa_key(rsa, sp);
-		if (h_pub_key == CK_INVALID_HANDLE)
-			goto err;
-		}
-	else
-		if ((pubkey = fopen(file, read_mode_flags)) != NULL)
-			{
-			pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
-			(void) fclose(pubkey);
-			if (pkey != NULL)
-				{
-				rsa = EVP_PKEY_get1_RSA(pkey);
-				if (rsa != NULL)
-					{
-					/*
-					 * This will always destroy the RSA
-					 * object since we have a new RSA
-					 * structure here.
-					 */
-					(void) pk11_check_new_rsa_key_pub(sp,
-					    rsa);
-
-					h_pub_key = sp->opdata_rsa_pub_key =
-					    pk11_get_public_rsa_key(rsa, sp);
-					if (h_pub_key == CK_INVALID_HANDLE)
-						{
-						EVP_PKEY_free(pkey);
-						pkey = NULL;
-						}
-					}
-				else
-					{
-					EVP_PKEY_free(pkey);
-					pkey = NULL;
-					}
-				}
-			}
-
-	pk11_return_session(sp, OP_RSA);
-	return (pkey);
-err:
-	if (rsa != NULL)
-		RSA_free(rsa);
-	if (pkey != NULL)
-		{
-		EVP_PKEY_free(pkey);
-		pkey = NULL;
-		}
-	return (pkey);
-	}
-
-/*
- * Get a public key object in a session from a given rsa structure. If the
- * PKCS#11 session object already exists it is found, reused, and
- * the counter in the active object list incremented. If not found, a new
- * session object is created and put also onto the active object list.
- *
- * We use the session field from sp, and we cache rsa->(n|e) in
- * opdata_rsa_(n|e|d)_num, respectively.
- */
-static CK_OBJECT_HANDLE
-pk11_get_public_rsa_key(RSA* rsa, PK11_SESSION *sp)
-	{
-	CK_RV rv;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	CK_ULONG found;
-	CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
-	CK_KEY_TYPE k_type = CKK_RSA;
-	CK_ULONG ul_key_attr_count = 7;
-	CK_BBOOL rollback = CK_FALSE;
-
-	CK_ATTRIBUTE  a_key_template[] =
-		{
-		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
-		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
-		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
-		{CKA_ENCRYPT, &pk11_true, sizeof (pk11_true)},
-		{CKA_VERIFY_RECOVER, &pk11_true, sizeof (pk11_true)},
-		{CKA_MODULUS, (void *)NULL, 0},
-		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
-		};
-
-	int i;
-
-	a_key_template[0].pValue = &o_key;
-	a_key_template[1].pValue = &k_type;
-
-	a_key_template[5].ulValueLen = BN_num_bytes(rsa->n);
-	a_key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-		(size_t)a_key_template[5].ulValueLen);
-	if (a_key_template[5].pValue == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	BN_bn2bin(rsa->n, a_key_template[5].pValue);
-
-	a_key_template[6].ulValueLen = BN_num_bytes(rsa->e);
-	a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-		(size_t)a_key_template[6].ulValueLen);
-	if (a_key_template[6].pValue == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	BN_bn2bin(rsa->e, a_key_template[6].pValue);
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(OP_RSA);
-
-	rv = pFuncList->C_FindObjectsInit(sp->session, a_key_template,
-		ul_key_attr_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
-		    PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(sp->session, &h_key, 1, &found);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
-		    PK11_R_FINDOBJECTS, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjectsFinal(sp->session);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
-		    PK11_R_FINDOBJECTSFINAL, rv);
-		goto err;
-		}
-
-	if (found == 0)
-		{
-		rv = pFuncList->C_CreateObject(sp->session,
-			a_key_template, ul_key_attr_count, &h_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
-			    PK11_R_CREATEOBJECT, rv);
-			goto err;
-			}
-		}
-
-	if ((sp->opdata_rsa_n_num = BN_dup(rsa->n)) == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		rollback = CK_TRUE;
-		goto err;
-		}
-
-	if ((sp->opdata_rsa_e_num = BN_dup(rsa->e)) == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		BN_free(sp->opdata_rsa_n_num);
-		sp->opdata_rsa_n_num = NULL;
-		rollback = CK_TRUE;
-		goto err;
-		}
-
-	/* LINTED: E_CONSTANT_CONDITION */
-	KEY_HANDLE_REFHOLD(h_key, OP_RSA, CK_FALSE, rollback, err);
-	sp->opdata_rsa_pub = rsa;
-
-err:
-	if (rollback)
-		{
-		/*
-		 * We do not care about the return value from C_DestroyObject()
-		 * since we are doing rollback.
-		 */
-		if (found == 0)
-			(void) pFuncList->C_DestroyObject(sp->session, h_key);
-		h_key = CK_INVALID_HANDLE;
-		}
-
-	UNLOCK_OBJSTORE(OP_RSA);
-
-malloc_err:
-	for (i = 5; i <= 6; i++)
-		{
-		if (a_key_template[i].pValue != NULL)
-			{
-			OPENSSL_free(a_key_template[i].pValue);
-			a_key_template[i].pValue = NULL;
-			}
-		}
-
-	return (h_key);
-	}
-
-/*
- * Function similar to pk11_get_public_rsa_key(). In addition to 'n' and 'e'
- * components, it also caches 'd' if present. Note that if RSA keys by reference
- * are used, 'd' is never extracted from the token in which case it would be
- * NULL here.
- */
-static CK_OBJECT_HANDLE
-pk11_get_private_rsa_key(RSA* rsa, PK11_SESSION *sp)
-	{
-	CK_RV rv;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	int i;
-	CK_ULONG found;
-	CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
-	CK_KEY_TYPE k_type = CKK_RSA;
-	CK_ULONG ul_key_attr_count = 14;
-	CK_BBOOL rollback = CK_FALSE;
-
-	/*
-	 * Both CKA_TOKEN and CKA_SENSITIVE have to be CK_FALSE for session keys
-	 */
-	CK_ATTRIBUTE  a_key_template[] =
-		{
-		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
-		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
-		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
-		{CKA_SENSITIVE, &pk11_false, sizeof (pk11_false)},
-		{CKA_DECRYPT, &pk11_true, sizeof (pk11_true)},
-		{CKA_SIGN, &pk11_true, sizeof (pk11_true)},
-		{CKA_MODULUS, (void *)NULL, 0},
-		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
-		{CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
-		{CKA_PRIME_1, (void *)NULL, 0},
-		{CKA_PRIME_2, (void *)NULL, 0},
-		{CKA_EXPONENT_1, (void *)NULL, 0},
-		{CKA_EXPONENT_2, (void *)NULL, 0},
-		{CKA_COEFFICIENT, (void *)NULL, 0},
-		};
-
-	a_key_template[0].pValue = &o_key;
-	a_key_template[1].pValue = &k_type;
-
-	/* Put the private key components into the template */
-	if (init_template_value(rsa->n, &a_key_template[6].pValue,
-		&a_key_template[6].ulValueLen) == 0 ||
-	    init_template_value(rsa->e, &a_key_template[7].pValue,
-		&a_key_template[7].ulValueLen) == 0 ||
-	    init_template_value(rsa->d, &a_key_template[8].pValue,
-		&a_key_template[8].ulValueLen) == 0 ||
-	    init_template_value(rsa->p, &a_key_template[9].pValue,
-		&a_key_template[9].ulValueLen) == 0 ||
-	    init_template_value(rsa->q, &a_key_template[10].pValue,
-		&a_key_template[10].ulValueLen) == 0 ||
-	    init_template_value(rsa->dmp1, &a_key_template[11].pValue,
-		&a_key_template[11].ulValueLen) == 0 ||
-	    init_template_value(rsa->dmq1, &a_key_template[12].pValue,
-		&a_key_template[12].ulValueLen) == 0 ||
-	    init_template_value(rsa->iqmp, &a_key_template[13].pValue,
-		&a_key_template[13].ulValueLen) == 0)
-		{
-		PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(OP_RSA);
-
-	/*
-	 * We are getting the private key but the private 'd' component is NULL.
-	 * That means this is key by reference RSA key. In that case, we can
-	 * use only public components for searching for the private key handle.
-	 */
-	if (rsa->d == NULL)
-		{
-		ul_key_attr_count = 8;
-		/*
-		 * We will perform the search in the token, not in the existing
-		 * session keys.
-		 */
-		a_key_template[2].pValue = &pk11_true;
-		}
-
-	rv = pFuncList->C_FindObjectsInit(sp->session, a_key_template,
-		ul_key_attr_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
-		    PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(sp->session, &h_key, 1, &found);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
-		    PK11_R_FINDOBJECTS, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjectsFinal(sp->session);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
-		    PK11_R_FINDOBJECTSFINAL, rv);
-		goto err;
-		}
-
-	if (found == 0)
-		{
-		/*
-		 * We have an RSA structure with 'n'/'e' components only so we
-		 * tried to find the private key in the keystore. If it was
-		 * really a token key we have a problem. Note that for other key
-		 * types we just create a new session key using the private
-		 * components from the RSA structure.
-		 */
-		if (rsa->d == NULL)
-			{
-			PK11err(PK11_F_GET_PRIV_RSA_KEY,
-			    PK11_R_PRIV_KEY_NOT_FOUND);
-			goto err;
-			}
-
-		rv = pFuncList->C_CreateObject(sp->session,
-			a_key_template, ul_key_attr_count, &h_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
-				PK11_R_CREATEOBJECT, rv);
-			goto err;
-			}
-		}
-
-	/*
-	 * When RSA keys by reference code is used, we never extract private
-	 * components from the keystore. In that case 'd' was set to NULL and we
-	 * expect the application to properly cope with that. It is documented
-	 * in openssl(5). In general, if keys by reference are used we expect it
-	 * to be used exclusively using the high level API and then there is no
-	 * problem. If the application expects the private components to be read
-	 * from the keystore then that is not a supported way of usage.
-	 */
-	if (rsa->d != NULL)
-		{
-		if ((sp->opdata_rsa_d_num = BN_dup(rsa->d)) == NULL)
-			{
-			PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
-			rollback = CK_TRUE;
-			goto err;
-			}
-		}
-	else
-		sp->opdata_rsa_d_num = NULL;
-
-	/*
-	 * For the key by reference code, we need public components as well
-	 * since 'd' component is always NULL. For that reason, we always cache
-	 * 'n'/'e' components as well.
-	 */
-	if ((sp->opdata_rsa_n_num = BN_dup(rsa->n)) == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		sp->opdata_rsa_n_num = NULL;
-		rollback = CK_TRUE;
-		goto err;
-		}
-	if ((sp->opdata_rsa_e_num = BN_dup(rsa->e)) == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		BN_free(sp->opdata_rsa_n_num);
-		sp->opdata_rsa_n_num = NULL;
-		rollback = CK_TRUE;
-		goto err;
-		}
-
-	/* LINTED: E_CONSTANT_CONDITION */
-	KEY_HANDLE_REFHOLD(h_key, OP_RSA, CK_FALSE, rollback, err);
-	sp->opdata_rsa_priv = rsa;
-
-err:
-	if (rollback)
-		{
-		/*
-		 * We do not care about the return value from C_DestroyObject()
-		 * since we are doing rollback.
-		 */
-		if (found == 0)
-			(void) pFuncList->C_DestroyObject(sp->session, h_key);
-		h_key = CK_INVALID_HANDLE;
-		}
-
-	UNLOCK_OBJSTORE(OP_RSA);
-
-malloc_err:
-	/*
-	 * 6 to 13 entries in the key template are key components.
-	 * They need to be freed upon exit or error.
-	 */
-	for (i = 6; i <= 13; i++)
-		{
-		if (a_key_template[i].pValue != NULL)
-			{
-			(void) memset(a_key_template[i].pValue, 0,
-				a_key_template[i].ulValueLen);
-			OPENSSL_free(a_key_template[i].pValue);
-			a_key_template[i].pValue = NULL;
-			}
-		}
-
-	return (h_key);
-	}
-
-/*
- * Check for cache miss. Objects are cleaned only if we have a full cache miss,
- * meaning that it's a different RSA key pair. Return 1 for cache hit, 0 for
- * cache miss.
- */
-static int
-pk11_check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
-	{
-	/*
-	 * Provide protection against RSA structure reuse by making the
-	 * check for cache hit stronger. Only public components of RSA
-	 * key matter here so it is sufficient to compare them with values
-	 * cached in PK11_SESSION structure.
-	 *
-	 * We must check the handle as well since with key by reference, public
-	 * components 'n'/'e' are cached in private keys as well. That means we
-	 * could have a cache hit in a private key when looking for a public
-	 * key. That would not work, you cannot have one PKCS#11 object for
-	 * both data signing and verifying.
-	 */
-	if (sp->opdata_rsa_pub == rsa &&
-	    BN_cmp(sp->opdata_rsa_n_num, rsa->n) == 0 &&
-	    BN_cmp(sp->opdata_rsa_e_num, rsa->e) == 0)
-		{
-		if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
-			return (1);
-		else
-			/*
-			 * No public key object yet but we have the right RSA
-			 * structure with potentially existing private key
-			 * object. We can just create a public object and move
-			 * on with this session structure.
-			 */
-			return (0);
-		}
-
-	/*
-	 * A different RSA key pair was using this session structure previously
-	 * or it's an empty structure. Destroy what we can.
-	 */
-	(void) pk11_destroy_rsa_object_pub(sp, CK_TRUE);
-	(void) pk11_destroy_rsa_object_priv(sp, CK_TRUE);
-	return (0);
-	}
-
-/*
- * Check for cache miss. Objects are cleaned only if we have a full cache miss,
- * meaning that it's a different RSA key pair. Return 1 for cache hit, 0 for
- * cache miss.
- */
-static int
-pk11_check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
-	{
-	/*
-	 * Provide protection against RSA structure reuse by making the
-	 * check for cache hit stronger. Comparing public exponent of RSA
-	 * key with value cached in PK11_SESSION structure should
-	 * be sufficient. Note that we want to compare the public component
-	 * since with the keys by reference mechanism, private components are
-	 * not in the RSA structure. Also, see pk11_check_new_rsa_key_pub()
-	 * about why we compare the handle as well.
-	 */
-	if (sp->opdata_rsa_priv == rsa &&
-	    BN_cmp(sp->opdata_rsa_n_num, rsa->n) == 0 &&
-	    BN_cmp(sp->opdata_rsa_e_num, rsa->e) == 0)
-		{
-		if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
-			return (1);
-		else
-			/*
-			 * No private key object yet but we have the right RSA
-			 * structure with potentially existing public key
-			 * object. We can just create a private object and move
-			 * on with this session structure.
-			 */
-			return (0);
-		}
-
-	/*
-	 * A different RSA key pair was using this session structure previously
-	 * or it's an empty structure. Destroy what we can.
-	 */
-	(void) pk11_destroy_rsa_object_priv(sp, CK_TRUE);
-	(void) pk11_destroy_rsa_object_pub(sp, CK_TRUE);
-	return (0);
-	}
-#endif
-
-#ifndef OPENSSL_NO_DSA
-/* The DSA function implementation */
-/* ARGSUSED */
-static int pk11_DSA_init(DSA *dsa)
-	{
-	return (1);
-	}
-
-/* ARGSUSED */
-static int pk11_DSA_finish(DSA *dsa)
-	{
-	return (1);
-	}
-
-
-static DSA_SIG *
-pk11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
-	{
-	BIGNUM *r = NULL, *s = NULL;
-	int i;
-	DSA_SIG *dsa_sig = NULL;
-
-	CK_RV rv;
-	CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
-	CK_MECHANISM *p_mech = &Mechanism_dsa;
-	CK_OBJECT_HANDLE h_priv_key;
-
-	/*
-	 * The signature is the concatenation of r and s,
-	 * each is 20 bytes long
-	 */
-	unsigned char sigret[DSA_SIGNATURE_LEN];
-	unsigned long siglen = DSA_SIGNATURE_LEN;
-	unsigned int siglen2 = DSA_SIGNATURE_LEN / 2;
-
-	PK11_SESSION *sp = NULL;
-
-	if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_MISSING_KEY_COMPONENT);
-		goto ret;
-		}
-
-	i = BN_num_bytes(dsa->q); /* should be 20 */
-	if (dlen > i)
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_INVALID_SIGNATURE_LENGTH);
-		goto ret;
-		}
-
-	if ((sp = pk11_get_session(OP_DSA)) == NULL)
-		goto ret;
-
-	(void) check_new_dsa_key_priv(sp, dsa);
-
-	h_priv_key = sp->opdata_dsa_priv_key;
-	if (h_priv_key == CK_INVALID_HANDLE)
-		h_priv_key = sp->opdata_dsa_priv_key =
-			pk11_get_private_dsa_key((DSA *)dsa,
-			    &sp->opdata_dsa_priv,
-			    &sp->opdata_dsa_priv_num, sp->session);
-
-	if (h_priv_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGNINIT, rv);
-			goto ret;
-			}
-
-			(void) memset(sigret, 0, siglen);
-			rv = pFuncList->C_Sign(sp->session,
-			    (unsigned char *) dgst, dlen, sigret,
-			    (CK_ULONG_PTR) &siglen);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGN, rv);
-			goto ret;
-			}
-		}
-
-
-	if ((s = BN_new()) == NULL)
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
-		goto ret;
-		}
-
-	if ((r = BN_new()) == NULL)
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
-		goto ret;
-		}
-
-	if ((dsa_sig = DSA_SIG_new()) == NULL)
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
-		goto ret;
-		}
-
-	if (BN_bin2bn(sigret, siglen2, r) == NULL ||
-	    BN_bin2bn(&sigret[siglen2], siglen2, s) == NULL)
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
-		goto ret;
-		}
-
-	dsa_sig->r = r;
-	dsa_sig->s = s;
-
-ret:
-	if (dsa_sig == NULL)
-		{
-		if (r != NULL)
-			BN_free(r);
-		if (s != NULL)
-			BN_free(s);
-		}
-
-	pk11_return_session(sp, OP_DSA);
-	return (dsa_sig);
-	}
-
-static int
-pk11_dsa_do_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig,
-	DSA *dsa)
-	{
-	int i;
-	CK_RV rv;
-	int retval = 0;
-	CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
-	CK_MECHANISM *p_mech = &Mechanism_dsa;
-	CK_OBJECT_HANDLE h_pub_key;
-
-	unsigned char sigbuf[DSA_SIGNATURE_LEN];
-	unsigned long siglen = DSA_SIGNATURE_LEN;
-	unsigned long siglen2 = DSA_SIGNATURE_LEN/2;
-
-	PK11_SESSION *sp = NULL;
-
-	if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
-		{
-		PK11err(PK11_F_DSA_VERIFY,
-			PK11_R_INVALID_DSA_SIGNATURE_R);
-		goto ret;
-		}
-
-	if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
-		{
-		PK11err(PK11_F_DSA_VERIFY,
-			PK11_R_INVALID_DSA_SIGNATURE_S);
-		goto ret;
-		}
-
-	i = BN_num_bytes(dsa->q); /* should be 20 */
-
-	if (dlen > i)
-		{
-		PK11err(PK11_F_DSA_VERIFY,
-			PK11_R_INVALID_SIGNATURE_LENGTH);
-		goto ret;
-		}
-
-	if ((sp = pk11_get_session(OP_DSA)) == NULL)
-		goto ret;
-
-	(void) check_new_dsa_key_pub(sp, dsa);
-
-	h_pub_key = sp->opdata_dsa_pub_key;
-	if (h_pub_key == CK_INVALID_HANDLE)
-		h_pub_key = sp->opdata_dsa_pub_key =
-			pk11_get_public_dsa_key((DSA *)dsa, &sp->opdata_dsa_pub,
-			    &sp->opdata_dsa_pub_num, sp->session);
-
-	if (h_pub_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_VerifyInit(sp->session, p_mech,
-			h_pub_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFYINIT,
-			    rv);
-			goto ret;
-			}
-
-		/*
-		 * The representation of each of the two big numbers could
-		 * be shorter than DSA_SIGNATURE_LEN/2 bytes so we need
-		 * to act accordingly and shift if necessary.
-		 */
-		(void) memset(sigbuf, 0, siglen);
-		BN_bn2bin(sig->r, sigbuf + siglen2 - BN_num_bytes(sig->r));
-		BN_bn2bin(sig->s, &sigbuf[siglen2] + siglen2 -
-		    BN_num_bytes(sig->s));
-
-		rv = pFuncList->C_Verify(sp->session,
-			(unsigned char *) dgst, dlen, sigbuf, (CK_ULONG)siglen);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFY, rv);
-			goto ret;
-			}
-		}
-
-	retval = 1;
-ret:
-
-	pk11_return_session(sp, OP_DSA);
-	return (retval);
-	}
-
-
-/*
- * Create a public key object in a session from a given dsa structure.
- * The *dsa_pub_num pointer is non-NULL for DSA public keys.
- */
-static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa,
-    DSA **key_ptr, BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session)
-	{
-	CK_RV rv;
-	CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	CK_ULONG found;
-	CK_KEY_TYPE k_type = CKK_DSA;
-	CK_ULONG ul_key_attr_count = 8;
-	CK_BBOOL rollback = CK_FALSE;
-	int i;
-
-	CK_ATTRIBUTE  a_key_template[] =
-		{
-		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
-		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
-		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
-		{CKA_VERIFY, &pk11_true, sizeof (pk11_true)},
-		{CKA_PRIME, (void *)NULL, 0},		/* p */
-		{CKA_SUBPRIME, (void *)NULL, 0},	/* q */
-		{CKA_BASE, (void *)NULL, 0},		/* g */
-		{CKA_VALUE, (void *)NULL, 0}		/* pub_key - y */
-		};
-
-	a_key_template[0].pValue = &o_key;
-	a_key_template[1].pValue = &k_type;
-
-	if (init_template_value(dsa->p, &a_key_template[4].pValue,
-		&a_key_template[4].ulValueLen) == 0 ||
-	    init_template_value(dsa->q, &a_key_template[5].pValue,
-		&a_key_template[5].ulValueLen) == 0 ||
-	    init_template_value(dsa->g, &a_key_template[6].pValue,
-		&a_key_template[6].ulValueLen) == 0 ||
-	    init_template_value(dsa->pub_key, &a_key_template[7].pValue,
-		&a_key_template[7].ulValueLen) == 0)
-		{
-		PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(OP_DSA);
-	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
-		ul_key_attr_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
-		    PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
-		    PK11_R_FINDOBJECTS, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjectsFinal(session);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
-		    PK11_R_FINDOBJECTSFINAL, rv);
-		goto err;
-		}
-
-	if (found == 0)
-		{
-		rv = pFuncList->C_CreateObject(session,
-			a_key_template, ul_key_attr_count, &h_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
-			    PK11_R_CREATEOBJECT, rv);
-			goto err;
-			}
-		}
-
-	if (dsa_pub_num != NULL)
-		if ((*dsa_pub_num = BN_dup(dsa->pub_key)) == NULL)
-			{
-			PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
-			rollback = CK_TRUE;
-			goto err;
-			}
-
-	/* LINTED: E_CONSTANT_CONDITION */
-	KEY_HANDLE_REFHOLD(h_key, OP_DSA, CK_FALSE, rollback, err);
-	if (key_ptr != NULL)
-		*key_ptr = dsa;
-
-err:
-	if (rollback)
-		{
-		/*
-		 * We do not care about the return value from C_DestroyObject()
-		 * since we are doing rollback.
-		 */
-		if (found == 0)
-			(void) pFuncList->C_DestroyObject(session, h_key);
-		h_key = CK_INVALID_HANDLE;
-		}
-
-	UNLOCK_OBJSTORE(OP_DSA);
-
-malloc_err:
-	for (i = 4; i <= 7; i++)
-		{
-		if (a_key_template[i].pValue != NULL)
-			{
-			OPENSSL_free(a_key_template[i].pValue);
-			a_key_template[i].pValue = NULL;
-			}
-		}
-
-	return (h_key);
-	}
-
-/*
- * Create a private key object in the session from a given dsa structure
- * The *dsa_priv_num pointer is non-NULL for DSA private keys.
- */
-static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa,
-    DSA **key_ptr, BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session)
-	{
-	CK_RV rv;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
-	int i;
-	CK_ULONG found;
-	CK_KEY_TYPE k_type = CKK_DSA;
-	CK_ULONG ul_key_attr_count = 9;
-	CK_BBOOL rollback = CK_FALSE;
-
-	/*
-	 * Both CKA_TOKEN and CKA_SENSITIVE have to be CK_FALSE for session keys
-	 */
-	CK_ATTRIBUTE  a_key_template[] =
-		{
-		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
-		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
-		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
-		{CKA_SENSITIVE, &pk11_false, sizeof (pk11_false)},
-		{CKA_SIGN, &pk11_true, sizeof (pk11_true)},
-		{CKA_PRIME, (void *)NULL, 0},		/* p */
-		{CKA_SUBPRIME, (void *)NULL, 0},	/* q */
-		{CKA_BASE, (void *)NULL, 0},		/* g */
-		{CKA_VALUE, (void *)NULL, 0}		/* priv_key - x */
-		};
-
-	a_key_template[0].pValue = &o_key;
-	a_key_template[1].pValue = &k_type;
-
-	/* Put the private key components into the template */
-	if (init_template_value(dsa->p, &a_key_template[5].pValue,
-		&a_key_template[5].ulValueLen) == 0 ||
-	    init_template_value(dsa->q, &a_key_template[6].pValue,
-		&a_key_template[6].ulValueLen) == 0 ||
-	    init_template_value(dsa->g, &a_key_template[7].pValue,
-		&a_key_template[7].ulValueLen) == 0 ||
-	    init_template_value(dsa->priv_key, &a_key_template[8].pValue,
-		&a_key_template[8].ulValueLen) == 0)
-		{
-		PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(OP_DSA);
-	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
-		ul_key_attr_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
-		    PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
-		    PK11_R_FINDOBJECTS, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjectsFinal(session);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
-		    PK11_R_FINDOBJECTSFINAL, rv);
-		goto err;
-		}
-
-	if (found == 0)
-		{
-		rv = pFuncList->C_CreateObject(session,
-			a_key_template, ul_key_attr_count, &h_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
-			    PK11_R_CREATEOBJECT, rv);
-			goto err;
-			}
-		}
-
-	if (dsa_priv_num != NULL)
-		if ((*dsa_priv_num = BN_dup(dsa->priv_key)) == NULL)
-			{
-			PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
-			rollback = CK_TRUE;
-			goto err;
-			}
-
-	/* LINTED: E_CONSTANT_CONDITION */
-	KEY_HANDLE_REFHOLD(h_key, OP_DSA, CK_FALSE, rollback, err);
-	if (key_ptr != NULL)
-		*key_ptr = dsa;
-
-err:
-	if (rollback)
-		{
-		/*
-		 * We do not care about the return value from C_DestroyObject()
-		 * since we are doing rollback.
-		 */
-		if (found == 0)
-			(void) pFuncList->C_DestroyObject(session, h_key);
-		h_key = CK_INVALID_HANDLE;
-		}
-
-	UNLOCK_OBJSTORE(OP_DSA);
-
-malloc_err:
-	/*
-	 * 5 to 8 entries in the key template are key components.
-	 * They need to be freed apon exit or error.
-	 */
-	for (i = 5; i <= 8; i++)
-		{
-		if (a_key_template[i].pValue != NULL)
-			{
-			(void) memset(a_key_template[i].pValue, 0,
-				a_key_template[i].ulValueLen);
-			OPENSSL_free(a_key_template[i].pValue);
-			a_key_template[i].pValue = NULL;
-			}
-		}
-
-	return (h_key);
-	}
-
-/*
- * Check for cache miss and clean the object pointer and handle
- * in such case. Return 1 for cache hit, 0 for cache miss.
- */
-static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa)
-	{
-	/*
-	 * Provide protection against DSA structure reuse by making the
-	 * check for cache hit stronger. Only public key component of DSA
-	 * key matters here so it is sufficient to compare it with value
-	 * cached in PK11_SESSION structure.
-	 */
-	if ((sp->opdata_dsa_pub != dsa) ||
-	    (BN_cmp(sp->opdata_dsa_pub_num, dsa->pub_key) != 0))
-		{
-		/*
-		 * We do not check the return value because even in case of
-		 * failure the sp structure will have both key pointer
-		 * and object handle cleaned and pk11_destroy_object()
-		 * reports the failure to the OpenSSL error message buffer.
-		 */
-		(void) pk11_destroy_dsa_object_pub(sp, CK_TRUE);
-		return (0);
-		}
-	return (1);
-	}
-
-/*
- * Check for cache miss and clean the object pointer and handle
- * in such case. Return 1 for cache hit, 0 for cache miss.
- */
-static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa)
-	{
-	/*
-	 * Provide protection against DSA structure reuse by making the
-	 * check for cache hit stronger. Only private key component of DSA
-	 * key matters here so it is sufficient to compare it with value
-	 * cached in PK11_SESSION structure.
-	 */
-	if ((sp->opdata_dsa_priv != dsa) ||
-	    (BN_cmp(sp->opdata_dsa_priv_num, dsa->priv_key) != 0))
-		{
-		/*
-		 * We do not check the return value because even in case of
-		 * failure the sp structure will have both key pointer
-		 * and object handle cleaned and pk11_destroy_object()
-		 * reports the failure to the OpenSSL error message buffer.
-		 */
-		(void) pk11_destroy_dsa_object_priv(sp, CK_TRUE);
-		return (0);
-		}
-	return (1);
-	}
-#endif
-
-
-#ifndef OPENSSL_NO_DH
-/* The DH function implementation */
-/* ARGSUSED */
-static int pk11_DH_init(DH *dh)
-	{
-	return (1);
-	}
-
-/* ARGSUSED */
-static int pk11_DH_finish(DH *dh)
-	{
-	return (1);
-	}
-
-/*
- * Generate DH key-pair.
- *
- * Warning: Unlike OpenSSL's DH_generate_key(3) we ignore dh->priv_key
- * and override it even if it is set. OpenSSL does not touch dh->priv_key
- * if set and just computes dh->pub_key. It looks like PKCS#11 standard
- * is not capable of providing this functionality. This could be a problem
- * for applications relying on OpenSSL's semantics.
- */
-static int pk11_DH_generate_key(DH *dh)
-	{
-	CK_ULONG i;
-	CK_RV rv, rv1;
-	int reuse_mem_len = 0, ret = 0;
-	PK11_SESSION *sp = NULL;
-	CK_BYTE_PTR reuse_mem;
-
-	CK_MECHANISM mechanism = {CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
-	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
-	CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
-
-	CK_ULONG ul_pub_key_attr_count = 3;
-	CK_ATTRIBUTE pub_key_template[] =
-		{
-		{CKA_PRIVATE, &pk11_false, sizeof (pk11_false)},
-		{CKA_PRIME, (void *)NULL, 0},
-		{CKA_BASE, (void *)NULL, 0}
-		};
-
-	CK_ULONG ul_priv_key_attr_count = 3;
-	CK_ATTRIBUTE priv_key_template[] =
-		{
-		{CKA_PRIVATE, &pk11_false, sizeof (pk11_false)},
-		{CKA_SENSITIVE, &pk11_false, sizeof (pk11_false)},
-		{CKA_DERIVE, &pk11_true, sizeof (pk11_true)}
-		};
-
-	CK_ULONG pub_key_attr_result_count = 1;
-	CK_ATTRIBUTE pub_key_result[] =
-		{
-		{CKA_VALUE, (void *)NULL, 0}
-		};
-
-	CK_ULONG priv_key_attr_result_count = 1;
-	CK_ATTRIBUTE priv_key_result[] =
-		{
-		{CKA_VALUE, (void *)NULL, 0}
-		};
-
-	pub_key_template[1].ulValueLen = BN_num_bytes(dh->p);
-	if (pub_key_template[1].ulValueLen > 0)
-		{
-		/*
-		 * We must not increase ulValueLen by DH_BUF_RESERVE since that
-		 * could cause the same rounding problem. See definition of
-		 * DH_BUF_RESERVE above.
-		 */
-		pub_key_template[1].pValue =
-			OPENSSL_malloc(pub_key_template[1].ulValueLen +
-			DH_BUF_RESERVE);
-		if (pub_key_template[1].pValue == NULL)
-			{
-			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-
-		i = BN_bn2bin(dh->p, pub_key_template[1].pValue);
-		}
-	else
-		goto err;
-
-	pub_key_template[2].ulValueLen = BN_num_bytes(dh->g);
-	if (pub_key_template[2].ulValueLen > 0)
-		{
-		pub_key_template[2].pValue =
-			OPENSSL_malloc(pub_key_template[2].ulValueLen +
-			DH_BUF_RESERVE);
-		if (pub_key_template[2].pValue == NULL)
-			{
-			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-
-		i = BN_bn2bin(dh->g, pub_key_template[2].pValue);
-		}
-	else
-		goto err;
-
-	/*
-	 * Note: we are only using PK11_SESSION structure for getting
-	 *	 a session handle. The objects created in this function are
-	 *	 destroyed before return and thus not cached.
-	 */
-	if ((sp = pk11_get_session(OP_DH)) == NULL)
-		goto err;
-
-	rv = pFuncList->C_GenerateKeyPair(sp->session,
-	    &mechanism,
-	    pub_key_template,
-	    ul_pub_key_attr_count,
-	    priv_key_template,
-	    ul_priv_key_attr_count,
-	    &h_pub_key,
-	    &h_priv_key);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_GEN_KEY, PK11_R_GEN_KEY, rv);
-		goto err;
-		}
-
-	/*
-	 * Reuse the larger memory allocated. We know the larger memory
-	 * should be sufficient for reuse.
-	 */
-	if (pub_key_template[1].ulValueLen > pub_key_template[2].ulValueLen)
-		{
-		reuse_mem = pub_key_template[1].pValue;
-		reuse_mem_len = pub_key_template[1].ulValueLen + DH_BUF_RESERVE;
-		}
-	else
-		{
-		reuse_mem = pub_key_template[2].pValue;
-		reuse_mem_len = pub_key_template[2].ulValueLen + DH_BUF_RESERVE;
-		}
-
-	rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
-		pub_key_result, pub_key_attr_result_count);
-	rv1 = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
-		priv_key_result, priv_key_attr_result_count);
-
-	if (rv != CKR_OK || rv1 != CKR_OK)
-		{
-		rv = (rv != CKR_OK) ? rv : rv1;
-		PK11err_add_data(PK11_F_DH_GEN_KEY,
-		    PK11_R_GETATTRIBUTVALUE, rv);
-		goto err;
-		}
-
-	if (((CK_LONG) pub_key_result[0].ulValueLen) <= 0 ||
-		((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
-		{
-		PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
-		goto err;
-		}
-
-	/* Reuse the memory allocated */
-	pub_key_result[0].pValue = reuse_mem;
-	pub_key_result[0].ulValueLen = reuse_mem_len;
-
-	rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
-		pub_key_result, pub_key_attr_result_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_GEN_KEY,
-		    PK11_R_GETATTRIBUTVALUE, rv);
-		goto err;
-		}
-
-	if (pub_key_result[0].type == CKA_VALUE)
-		{
-		if (dh->pub_key == NULL)
-			if ((dh->pub_key = BN_new()) == NULL)
-				{
-				PK11err(PK11_F_DH_GEN_KEY,
-					PK11_R_MALLOC_FAILURE);
-				goto err;
-				}
-		dh->pub_key = BN_bin2bn(pub_key_result[0].pValue,
-			pub_key_result[0].ulValueLen, dh->pub_key);
-		if (dh->pub_key == NULL)
-			{
-			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		}
-
-	/* Reuse the memory allocated */
-	priv_key_result[0].pValue = reuse_mem;
-	priv_key_result[0].ulValueLen = reuse_mem_len;
-
-	rv = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
-		priv_key_result, priv_key_attr_result_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_GEN_KEY,
-		    PK11_R_GETATTRIBUTVALUE, rv);
-		goto err;
-		}
-
-	if (priv_key_result[0].type == CKA_VALUE)
-		{
-		if (dh->priv_key == NULL)
-			if ((dh->priv_key = BN_new()) == NULL)
-				{
-				PK11err(PK11_F_DH_GEN_KEY,
-					PK11_R_MALLOC_FAILURE);
-				goto err;
-				}
-		dh->priv_key = BN_bin2bn(priv_key_result[0].pValue,
-			priv_key_result[0].ulValueLen, dh->priv_key);
-		if (dh->priv_key == NULL)
-			{
-			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		}
-
-	ret = 1;
-
-err:
-
-	if (h_pub_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_DestroyObject(sp->session, h_pub_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DH_GEN_KEY,
-			    PK11_R_DESTROYOBJECT, rv);
-			}
-		}
-
-	if (h_priv_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_DestroyObject(sp->session, h_priv_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DH_GEN_KEY,
-			    PK11_R_DESTROYOBJECT, rv);
-			}
-		}
-
-	for (i = 1; i <= 2; i++)
-		{
-		if (pub_key_template[i].pValue != NULL)
-			{
-			OPENSSL_free(pub_key_template[i].pValue);
-			pub_key_template[i].pValue = NULL;
-			}
-		}
-
-	pk11_return_session(sp, OP_DH);
-	return (ret);
-	}
-
-static int pk11_DH_compute_key(unsigned char *key, const BIGNUM *pub_key,
-	DH *dh)
-	{
-	int i;
-	CK_MECHANISM mechanism = {CKM_DH_PKCS_DERIVE, NULL_PTR, 0};
-	CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
-	CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
-	CK_OBJECT_HANDLE h_derived_key = CK_INVALID_HANDLE;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-
-	CK_ULONG ul_priv_key_attr_count = 2;
-	CK_ATTRIBUTE priv_key_template[] =
-		{
-		{CKA_CLASS, (void*) NULL, sizeof (key_class)},
-		{CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
-		};
-
-	CK_ULONG priv_key_attr_result_count = 1;
-	CK_ATTRIBUTE priv_key_result[] =
-		{
-		{CKA_VALUE, (void *)NULL, 0}
-		};
-
-	CK_RV rv;
-	int ret = -1;
-	PK11_SESSION *sp = NULL;
-
-	if (dh->priv_key == NULL)
-		goto err;
-
-	priv_key_template[0].pValue = &key_class;
-	priv_key_template[1].pValue = &key_type;
-
-	if ((sp = pk11_get_session(OP_DH)) == NULL)
-		goto err;
-
-	mechanism.ulParameterLen = BN_num_bytes(pub_key);
-	mechanism.pParameter = OPENSSL_malloc(mechanism.ulParameterLen);
-	if (mechanism.pParameter == NULL)
-		{
-		PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-	BN_bn2bin(pub_key, mechanism.pParameter);
-
-	(void) check_new_dh_key(sp, dh);
-
-	h_key = sp->opdata_dh_key;
-	if (h_key == CK_INVALID_HANDLE)
-		h_key = sp->opdata_dh_key =
-			pk11_get_dh_key((DH*) dh, &sp->opdata_dh,
-			    &sp->opdata_dh_priv_num, sp->session);
-
-	if (h_key == CK_INVALID_HANDLE)
-		{
-		PK11err(PK11_F_DH_COMP_KEY, PK11_R_CREATEOBJECT);
-		goto err;
-		}
-
-	rv = pFuncList->C_DeriveKey(sp->session,
-	    &mechanism,
-	    h_key,
-	    priv_key_template,
-	    ul_priv_key_attr_count,
-	    &h_derived_key);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_DERIVEKEY, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
-	    priv_key_result, priv_key_attr_result_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
-		    rv);
-		goto err;
-		}
-
-	if (((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
-		{
-		PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
-		goto err;
-		}
-	priv_key_result[0].pValue =
-		OPENSSL_malloc(priv_key_result[0].ulValueLen);
-	if (!priv_key_result[0].pValue)
-		{
-		PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
-		priv_key_result, priv_key_attr_result_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
-		    rv);
-		goto err;
-		}
-
-	/*
-	 * OpenSSL allocates the output buffer 'key' which is the same
-	 * length of the public key. It is long enough for the derived key
-	 */
-	if (priv_key_result[0].type == CKA_VALUE)
-		{
-		/*
-		 * CKM_DH_PKCS_DERIVE mechanism is not supposed to strip
-		 * leading zeros from a computed shared secret. However,
-		 * OpenSSL always did it so we must do the same here. The
-		 * vagueness of the spec regarding leading zero bytes was
-		 * finally cleared with TLS 1.1 (RFC 4346) saying that leading
-		 * zeros are stripped before the computed data is used as the
-		 * pre-master secret.
-		 */
-		for (i = 0; i < priv_key_result[0].ulValueLen; ++i)
-			{
-			if (((char *)priv_key_result[0].pValue)[i] != 0)
-				break;
-			}
-
-		(void) memcpy(key, ((char *)priv_key_result[0].pValue) + i,
-			priv_key_result[0].ulValueLen - i);
-		ret = priv_key_result[0].ulValueLen - i;
-		}
-
-err:
-
-	if (h_derived_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_DestroyObject(sp->session, h_derived_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DH_COMP_KEY,
-			    PK11_R_DESTROYOBJECT, rv);
-			}
-		}
-	if (priv_key_result[0].pValue)
-		{
-		OPENSSL_free(priv_key_result[0].pValue);
-		priv_key_result[0].pValue = NULL;
-		}
-
-	if (mechanism.pParameter)
-		{
-		OPENSSL_free(mechanism.pParameter);
-		mechanism.pParameter = NULL;
-		}
-
-	pk11_return_session(sp, OP_DH);
-	return (ret);
-	}
-
-
-static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh,
-	DH **key_ptr, BIGNUM **dh_priv_num, CK_SESSION_HANDLE session)
-	{
-	CK_RV rv;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
-	CK_KEY_TYPE key_type = CKK_DH;
-	CK_ULONG found;
-	CK_BBOOL rollback = CK_FALSE;
-	int i;
-
-	CK_ULONG ul_key_attr_count = 7;
-	CK_ATTRIBUTE key_template[] =
-		{
-		{CKA_CLASS, (void*) NULL, sizeof (class)},
-		{CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
-		{CKA_DERIVE, &pk11_true, sizeof (pk11_true)},
-		{CKA_PRIVATE, &pk11_false, sizeof (pk11_false)},
-		{CKA_PRIME, (void *) NULL, 0},
-		{CKA_BASE, (void *) NULL, 0},
-		{CKA_VALUE, (void *) NULL, 0},
-		};
-
-	key_template[0].pValue = &class;
-	key_template[1].pValue = &key_type;
-
-	key_template[4].ulValueLen = BN_num_bytes(dh->p);
-	key_template[4].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-		(size_t)key_template[4].ulValueLen);
-	if (key_template[4].pValue == NULL)
-		{
-		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	BN_bn2bin(dh->p, key_template[4].pValue);
-
-	key_template[5].ulValueLen = BN_num_bytes(dh->g);
-	key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-		(size_t)key_template[5].ulValueLen);
-	if (key_template[5].pValue == NULL)
-		{
-		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	BN_bn2bin(dh->g, key_template[5].pValue);
-
-	key_template[6].ulValueLen = BN_num_bytes(dh->priv_key);
-	key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-		(size_t)key_template[6].ulValueLen);
-	if (key_template[6].pValue == NULL)
-		{
-		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	BN_bn2bin(dh->priv_key, key_template[6].pValue);
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(OP_DH);
-	rv = pFuncList->C_FindObjectsInit(session, key_template,
-		ul_key_attr_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTS, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjectsFinal(session);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSFINAL,
-		    rv);
-		goto err;
-		}
-
-	if (found == 0)
-		{
-		rv = pFuncList->C_CreateObject(session,
-			key_template, ul_key_attr_count, &h_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_CREATEOBJECT,
-			    rv);
-			goto err;
-			}
-		}
-
-	if (dh_priv_num != NULL)
-		if ((*dh_priv_num = BN_dup(dh->priv_key)) == NULL)
-			{
-			PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
-			rollback = CK_TRUE;
-			goto err;
-			}
-
-	/* LINTED: E_CONSTANT_CONDITION */
-	KEY_HANDLE_REFHOLD(h_key, OP_DH, CK_FALSE, rollback, err);
-	if (key_ptr != NULL)
-		*key_ptr = dh;
-
-err:
-	if (rollback)
-		{
-		/*
-		 * We do not care about the return value from C_DestroyObject()
-		 * since we are doing rollback.
-		 */
-		if (found == 0)
-			(void) pFuncList->C_DestroyObject(session, h_key);
-		h_key = CK_INVALID_HANDLE;
-		}
-
-	UNLOCK_OBJSTORE(OP_DH);
-
-malloc_err:
-	for (i = 4; i <= 6; i++)
-		{
-		if (key_template[i].pValue != NULL)
-			{
-			OPENSSL_free(key_template[i].pValue);
-			key_template[i].pValue = NULL;
-			}
-		}
-
-	return (h_key);
-	}
-
-/*
- * Check for cache miss and clean the object pointer and handle
- * in such case. Return 1 for cache hit, 0 for cache miss.
- *
- * Note: we rely on pk11_destroy_dh_key_objects() to set sp->opdata_dh
- *       to CK_INVALID_HANDLE even when it fails to destroy the object.
- */
-static int check_new_dh_key(PK11_SESSION *sp, DH *dh)
-	{
-	/*
-	 * Provide protection against DH structure reuse by making the
-	 * check for cache hit stronger. Private key component of DH key
-	 * is unique so it is sufficient to compare it with value cached
-	 * in PK11_SESSION structure.
-	 */
-	if ((sp->opdata_dh != dh) ||
-	    (BN_cmp(sp->opdata_dh_priv_num, dh->priv_key) != 0))
-		{
-		/*
-		 * We do not check the return value because even in case of
-		 * failure the sp structure will have both key pointer
-		 * and object handle cleaned and pk11_destroy_object()
-		 * reports the failure to the OpenSSL error message buffer.
-		 */
-		(void) pk11_destroy_dh_object(sp, CK_TRUE);
-		return (0);
-		}
-	return (1);
-	}
-#endif
-
-/*
- * Local function to simplify key template population
- * Return 0 -- error, 1 -- no error
- */
-static int
-init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
-	CK_ULONG *ul_value_len)
-	{
-	CK_ULONG len;
-
-	/*
-	 * This function can be used on non-initialized BIGNUMs. It is easier to
-	 * check that here than individually in the callers.
-	 */
-	if (bn != NULL)
-		len = BN_num_bytes(bn);
-
-	if (bn == NULL || len == 0)
-		return (1);
-
-	*ul_value_len = len;
-	*p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
-	if (*p_value == NULL)
-		return (0);
-
-	BN_bn2bin(bn, *p_value);
-
-	return (1);
-	}
-
-static void
-attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
-	{
-		if (attr->ulValueLen > 0)
-			*bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
-	}
-
-/*
- * Find one object in the token. It is an error if we can not find the object or
- * if we find more objects based on the template we got.
- *
- * Returns:
- *	1 OK
- *	0 no object or more than 1 object found
- */
-static int
-find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
-    CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey)
-	{
-	CK_RV rv;
-	CK_ULONG objcnt;
-
-	LOCK_OBJSTORE(op);
-	if ((rv = pFuncList->C_FindObjectsInit(s, ptempl, nattr)) != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_FIND_ONE_OBJECT,
-		    PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(s, pkey, 1, &objcnt);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_FIND_ONE_OBJECT, PK11_R_FINDOBJECTS,
-		    rv);
-		goto err;
-		}
-
-	if (objcnt > 1)
-		{
-		PK11err(PK11_F_FIND_ONE_OBJECT,
-		    PK11_R_MORE_THAN_ONE_OBJECT_FOUND);
-		goto err;
-		}
-	else
-		if (objcnt == 0)
-			{
-			PK11err(PK11_F_FIND_ONE_OBJECT, PK11_R_NO_OBJECT_FOUND);
-			goto err;
-			}
-
-	(void) pFuncList->C_FindObjectsFinal(s);
-	UNLOCK_OBJSTORE(op);
-	return (1);
-err:
-	UNLOCK_OBJSTORE(op);
-	return (0);
-	}
-
-#endif	/* OPENSSL_NO_HW_PK11 */
-#endif	/* OPENSSL_NO_HW */
--- a/components/openssl/openssl-0.9.8-fips-140/engines/pkcs11/e_pk11_uri.c	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,870 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- *
- */
-
-/*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    [email protected]
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <strings.h>
-#include <libgen.h>
-#include <pthread.h>
-#include <assert.h>
-#include <errno.h>
-
-#include <openssl/crypto.h>
-
-#ifndef OPENSSL_NO_HW
-#ifndef OPENSSL_NO_HW_PK11
-
-#include <security/cryptoki.h>
-#include <security/pkcs11.h>
-#include "e_pk11.h"
-#include "e_pk11_uri.h"
-
-/*
- * The keystore used is always from the pubkey slot so we need to know which one
- * was selected so that we can get the information needed for the URI
- * processing.
- */
-extern CK_SLOT_ID pubkey_SLOTID;
-extern CK_FUNCTION_LIST_PTR pFuncList;
-
-/*
- * Cached PIN so that child can use it during the re-login. Note that we do not
- * cache the PIN by default.
- */
-static char *token_pin;
-
-static int mlock_pin_in_memory(char *pin);
-static char *run_askpass(char *dialog);
-
-/*
- * Get the PIN. Either run the command and use its standard output as a PIN to
- * fill in the PKCS11 URI structure, or read the PIN from the terminal. Using
- * the external command is of higher precedence. The memory for PIN is allocated
- * in this function and the PIN is always NULL terminated. The caller must take
- * care of freeing the memory used for the PIN. The maximum PIN length accepted
- * is PK11_MAX_PIN_LEN.
- *
- * The function is used also during the re-initialization of the engine after
- * the fork.
- *
- * The function must not be called under the protection of the mutex "uri_lock"
- * because the lock is acquired in the prefork function.
- *
- * Returns:
- *	0 in case of troubles (and sets "*pin" to NULL)
- *	1 if we got the PIN
- */
-#define	EXEC_SPEC	"exec:"
-#define	BUILTIN_SPEC	"builtin"
-int
-pk11_get_pin(char *dialog, char **pin)
-	{
-	/* Initialize as an error. */
-	*pin = NULL;
-
-	if (strcmp(dialog, BUILTIN_SPEC) == 0)
-		{
-		/* The getpassphrase() function is not MT safe. */
-		(void) pthread_mutex_lock(uri_lock);
-		/* Note that OpenSSL is not localized at all. */
-		*pin = getpassphrase("Enter token PIN: ");
-		if (*pin == NULL)
-			{
-			PK11err(PK11_F_GET_PIN, PK11_R_COULD_NOT_READ_PIN);
-			(void) pthread_mutex_unlock(uri_lock);
-			goto err;
-			}
-		else
-			{
-			char *pw;
-
-			/*
-			 * getpassphrase() uses an internal  buffer to hold the
-			 * entered password. Note that it terminates the buffer
-			 * with '\0'.
-			 */
-			if ((pw = strdup(*pin)) == NULL)
-				{
-				PK11err(PK11_F_GET_PIN, PK11_R_MALLOC_FAILURE);
-				(void) pthread_mutex_unlock(uri_lock);
-				goto err;
-				}
-			/* Zero the internal buffer to get rid of the PIN. */
-			memset(*pin, 0, strlen(*pin));
-			*pin = pw;
-			(void) pthread_mutex_unlock(uri_lock);
-			}
-		}
-	else
-		{
-		/*
-		 * This is the "exec:" case. We will get the PIN from the output
-		 * of an external command.
-		 */
-		if (strncmp(dialog, EXEC_SPEC, strlen(EXEC_SPEC)) == 0)
-			{
-			dialog += strlen(EXEC_SPEC);
-			if ((*pin = run_askpass(dialog)) == NULL)
-				goto err;
-			}
-		else
-			{
-			/*
-			 * Invalid specification in the passphrasedialog
-			 * keyword.
-			 */
-			PK11err(PK11_F_GET_PIN, PK11_R_BAD_PASSPHRASE_SPEC);
-			goto err;
-			}
-		}
-
-	return (1);
-err:
-	return (0);
-	}
-
-/*
- * Process the PKCS#11 URI and get the PIN. It uses information from the
- * passphrasedialog keyword to get the PIN. If passphrasedialog is not present
- * it is not considered an error since it depends on the token attributes
- * whether C_Login() is required. The function expects an allocated 'uri_struct'
- * structure.
- *
- * Returns:
- *	0 if URI is not valid at all, or if we could not get the PIN
- * 	1 if all is OK
- *	2 if the URI is not the PKCS#11 URI. In that case, put the string
- *	pointer to the filename to "*file". Note that the pointer just points
- *	inside of the "uristr", possibly skipping the file:// prefix if present.
- */
-int
-pk11_process_pkcs11_uri(const char *uristr, pkcs11_uri *uri_struct,
-	const char **file)
-	{
-	char *uristr2, *l1, *l2, *tok, *name;
-
-	/* Check the "file://" case. */
-	if (strncmp(uristr, FILE_URI_PREFIX, strlen(FILE_URI_PREFIX)) == 0)
-		{
-		*file = uristr + strlen(FILE_URI_PREFIX);
-		return (2);
-		}
-
-	/*  This is the "pkcs11:" case. */
-	if (strncmp(uristr, PK11_URI_PREFIX, strlen(PK11_URI_PREFIX)) != 0)
-		{
-		/* Not PKCS#11 URI at all, could be a filename. */
-		*file = (const char *)uristr;
-		return (2);
-		}
-	else
-		{
-		/* Dup the string and skip over the pkcs11: prefix then. */
-		uristr2 = strdup(uristr + strlen(PK11_URI_PREFIX));
-		if (uristr2 == NULL)
-			{
-			PK11err(PK11_F_CHECK_TOKEN_ATTRS,
-			    PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		}
-
-	/* Initialize the structure. */
-	memset(uri_struct, 0, sizeof (*uri_struct));
-
-	/*
-	 * Using strtok_r() would silently skip over multiple semicolons. We
-	 * must check that before moving on. We must also avoid ';' as the first
-	 * and the last character in the URI.
-	 */
-	if (strstr(uristr2, ";;") != NULL || uristr2[0] == ';' ||
-	    (strlen(uristr2) > 0 && uristr2[strlen(uristr2) - 1] == ';'))
-		goto bad_uri;
-
-	tok = strtok_r(uristr2, ";", &l1);
-	for (; tok != NULL; tok = strtok_r(NULL, ";", &l1))
-		{
-		/* "tok" is not empty so there will be something in "name". */
-		name = strtok_r(tok, "=", &l2);
-		/* Check whether there is '=' at all. */
-		if (l2 == NULL)
-			goto bad_uri;
-
-		/*
-		 * Fill out the URI structure. We do not accept duplicit
-		 * attributes.
-		 */
-		if (strcmp(name, PK11_TOKEN) == 0)
-			if (uri_struct->token == NULL)
-				{
-				if ((uri_struct->token = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-		else if (strcmp(name, PK11_MANUF) == 0)
-			if (uri_struct->manuf == NULL)
-				{
-				if ((uri_struct->manuf = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-		else if (strcmp(name, PK11_SERIAL) == 0)
-			if (uri_struct->serial == NULL)
-				{
-				if ((uri_struct->serial = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-		else if (strcmp(name, PK11_MODEL) == 0)
-			if (uri_struct->model == NULL)
-				{
-				if ((uri_struct->model = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-		else if (strcmp(name, PK11_OBJECT) == 0)
-			if (uri_struct->object == NULL)
-				{
-				if ((uri_struct->object = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-		else if (strcmp(name, PK11_OBJECTTYPE) == 0)
-			if (uri_struct->objecttype == NULL)
-				{
-				uri_struct->objecttype = strdup(l2);
-				if (uri_struct->objecttype == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-		else if (strcmp(name, PK11_ASKPASS) == 0)
-			if (uri_struct->askpass == NULL)
-				{
-				if ((uri_struct->askpass = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-		else
-			goto bad_uri;
-		}
-
-	/* The "object" token is mandatory in the PKCS#11 URI. */
-	if (uri_struct->object == NULL)
-		{
-		PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MISSING_OBJECT_LABEL);
-		goto err;
-		}
-
-	free(uristr2);
-	return (1);
-bad_uri:
-	PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_INVALID_PKCS11_URI);
-	if (uristr2 != NULL)
-		free(uristr2);
-	return (0);
-no_mem:
-	PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
-err:
-	pk11_free_pkcs11_uri(uri_struct, CK_FALSE);
-	if (uristr2 != NULL)
-		free(uristr2);
-	return (0);
-	}
-
-/*
- * Free the PKCS11 URI structure and anything that might be inside.
- */
-void
-pk11_free_pkcs11_uri(pkcs11_uri *uri_struct, CK_BBOOL free_uri_itself)
-	{
-	if (uri_struct->token != NULL)
-		free(uri_struct->token);
-	if (uri_struct->manuf != NULL)
-		free(uri_struct->manuf);
-	if (uri_struct->serial != NULL)
-		free(uri_struct->serial);
-	if (uri_struct->model != NULL)
-		free(uri_struct->model);
-	if (uri_struct->object != NULL)
-		free(uri_struct->object);
-	if (uri_struct->objecttype != NULL)
-		free(uri_struct->objecttype);
-	if (uri_struct->askpass != NULL)
-		free(uri_struct->askpass);
-
-	if (free_uri_itself == CK_TRUE)
-		OPENSSL_free(uri_struct);
-	}
-
-/*
- * While our keystore is always the one used by the pubkey slot (which is
- * usually the Metaslot) we must make sure that those URI attributes that
- * specify the keystore match the real attributes of our slot keystore. Note
- * that one can use the METASLOT_OBJECTSTORE_TOKEN environment variable to
- * change the Metaslot's keystore from the softtoken to something else (see
- * libpkcs11(3LIB)). The user might want to use such attributes in the PKCS#11
- * URI to make sure that the intended keystore is used.
- *
- * Returns:
- *	1 on success
- *	0 on failure
- */
-int
-pk11_check_token_attrs(pkcs11_uri *uri_struct)
-	{
-	CK_RV rv;
-	static CK_TOKEN_INFO_PTR token_info = NULL;
-
-	(void) pthread_mutex_lock(uri_lock);
-	if (token_info == NULL)
-		{
-		token_info = OPENSSL_malloc(sizeof (CK_TOKEN_INFO));
-		if (token_info == NULL)
-			{
-			PK11err(PK11_F_CHECK_TOKEN_ATTRS,
-			    PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-
-		rv = pFuncList->C_GetTokenInfo(pubkey_SLOTID, token_info);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_CHECK_TOKEN_ATTRS,
-			    PK11_R_GETTOKENINFO, rv);
-			goto err;
-			}
-		}
-
-	if (uri_struct->token != NULL)
-		if (strncmp(uri_struct->token, (char *)token_info->label,
-		    strlen(uri_struct->token) > 32 ? 32 :
-		    strlen(uri_struct->token)) != 0)
-			{
-			goto urierr;
-			}
-
-	if (uri_struct->manuf != NULL)
-		if (strncmp(uri_struct->manuf,
-		    (char *)token_info->manufacturerID,
-		    strlen(uri_struct->manuf) > 32 ? 32 :
-		    strlen(uri_struct->manuf)) != 0)
-			goto urierr;
-
-	if (uri_struct->model != NULL)
-		if (strncmp(uri_struct->model, (char *)token_info->model,
-		    strlen(uri_struct->model) > 16 ? 16 :
-		    strlen(uri_struct->model)) != 0)
-			goto urierr;
-
-	if (uri_struct->serial != NULL)
-		if (strncmp(uri_struct->serial,
-		    (char *)token_info->serialNumber,
-		    strlen(uri_struct->serial) > 16 ? 16 :
-		    strlen(uri_struct->serial)) != 0)
-			goto urierr;
-
-	(void) pthread_mutex_unlock(uri_lock);
-	return (1);
-
-urierr:
-	PK11err(PK11_F_CHECK_TOKEN_ATTRS, PK11_R_TOKEN_ATTRS_DO_NOT_MATCH);
-	/* Correct error already set above for the "err" label. */
-err:
-	(void) pthread_mutex_unlock(uri_lock);
-	return (0);
-	}
-
-/*
- * Return the process PIN caching policy. We initialize it just once so if the
- * process change OPENSSL_PKCS11_PIN_CACHING_POLICY during the operation it will
- * not have any affect on the policy.
- *
- * We assume that the "uri_lock" mutex is already locked.
- *
- * Returns the caching policy number.
- */
-int
-pk11_get_pin_caching_policy(void)
-	{
-	char *value = NULL;
-	static int policy = POLICY_NOT_INITIALIZED;
-
-	if (policy != POLICY_NOT_INITIALIZED)
-		return (policy);
-
-	value = getenv("OPENSSL_PKCS11_PIN_CACHING_POLICY");
-
-	if (value == NULL || strcmp(value, "none") == 0)
-		{
-		policy = POLICY_NONE;
-		goto done;
-		}
-
-	if (strcmp(value, "memory") == 0)
-		{
-		policy = POLICY_MEMORY;
-		goto done;
-		}
-
-	if (strcmp(value, "mlocked-memory") == 0)
-		{
-		policy = POLICY_MLOCKED_MEMORY;
-		goto done;
-		}
-
-	return (POLICY_WRONG_VALUE);
-done:
-	return (policy);
-	}
-
-/*
- * Cache the PIN in memory once. We already know that we have either "memory" or
- * "mlocked-memory" keyword correctly set.
- *
- * Returns:
- *	1 on success
- *	0 on failure
- */
-int
-pk11_cache_pin(char *pin)
-	{
-	(void) pthread_mutex_lock(uri_lock);
-	/* We set the PIN only once since all URIs must have it the same. */
-	if (token_pin != NULL)
-		goto ok;
-
-	if (pk11_get_pin_caching_policy() == POLICY_MEMORY)
-		if ((token_pin = strdup(pin)) == NULL)
-			{
-			PK11err(PK11_F_CACHE_PIN, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-	else
-		if (pk11_get_pin_caching_policy() == POLICY_MLOCKED_MEMORY)
-			{
-			if (mlock_pin_in_memory(pin) == 0)
-				goto err;
-			}
-
-ok:
-	(void) pthread_mutex_unlock(uri_lock);
-	return (1);
-err:
-	(void) pthread_mutex_unlock(uri_lock);
-	return (0);
-	}
-
-/*
- * Cache the PIN in mlock(3C)ed memory. If mlock(3C) fails we will not resort to
- * the normal memory caching.
- *
- * Note that this function must be called under the protection of the "uri_lock"
- * mutex.
- *
- * Returns:
- *	1 on success
- *	0 on failure
- */
-static int
-mlock_pin_in_memory(char *pin)
-	{
-	void *addr = NULL;
-	long pagesize = 0;
-
-	/* mlock(3C) locks pages so we need one whole page for the PIN. */
-	if ((pagesize = sysconf(_SC_PAGESIZE)) == -1)
-		{
-		PK11err(PK11_F_MLOCK_PIN_IN_MEMORY, PK11_R_SYSCONF_FAILED);
-		goto err;
-		}
-
-	/* This will ensure we have a page aligned pointer... */
-	if ((addr = mmap(0, pagesize, PROT_READ | PROT_WRITE,
-	    MAP_PRIVATE | MAP_ANON, -1, 0)) == MAP_FAILED)
-		{
-		PK11err(PK11_F_MLOCK_PIN_IN_MEMORY, PK11_R_MMAP_FAILED);
-		goto err;
-		}
-
-	/* ...because "addr" must be page aligned here. */
-	if (mlock(addr, pagesize) == -1)
-		{
-		/*
-		 * Missing the PRIV_PROC_LOCK_MEMORY privilege might be a common
-		 * problem so distinguish this situation from other issues.
-		 */
-		if (errno == EPERM)
-			PK11err(PK11_F_MLOCK_PIN_IN_MEMORY,
-			    PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING);
-		else
-			PK11err(PK11_F_MLOCK_PIN_IN_MEMORY,
-			    PK11_R_MLOCK_FAILED);
-
-		/*
-		 * We already have a problem here so there is no need to check
-		 * that we could unmap the page. The PIN is not there yet
-		 * anyway.
-		 */
-		(void) munmap(addr, pagesize);
-		goto err;
-		}
-
-	/* Copy the PIN to the mlocked memory. */
-	token_pin = (char *)addr;
-	strlcpy(token_pin, pin, PK11_MAX_PIN_LEN + 1);
-	return (1);
-err:
-	return (0);
-	}
-
-/*
- * Log in to the keystore if we are supposed to do that at all. Take care of
- * reading and caching the PIN etc. Log in only once even when called from
- * multiple threads.
- *
- * Returns:
- *	1 on success
- *	0 on failure
- */
-int
-pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
-    pkcs11_uri *uri_struct, CK_BBOOL is_private)
-	{
-	CK_RV rv;
-
-	if ((pubkey_token_flags & CKF_TOKEN_INITIALIZED) == 0)
-		{
-		PK11err(PK11_F_TOKEN_LOGIN,
-		    PK11_R_TOKEN_NOT_INITIALIZED);
-		goto err;
-		}
-
-	/*
-	 * If login is required or needed but the PIN has not been even
-	 * initialized we can bail out right now. Note that we are supposed to
-	 * always log in if we are going to access private keys. However, we may
-	 * need to log in even for accessing public keys in case that the
-	 * CKF_LOGIN_REQUIRED flag is set.
-	 */
-	if ((pubkey_token_flags & CKF_LOGIN_REQUIRED ||
-	    is_private == CK_TRUE) && ~pubkey_token_flags &
-	    CKF_USER_PIN_INITIALIZED)
-		{
-		PK11err(PK11_F_TOKEN_LOGIN, PK11_R_TOKEN_PIN_NOT_SET);
-		goto err;
-		}
-
-	/*
-	 * Note on locking: it is possible that more than one thread gets into
-	 * pk11_get_pin() so we must deal with that. We cannot avoid it since we
-	 * cannot guard fork() in there with a lock because we could end up in
-	 * a dead lock in the child. Why? Remember we are in a multithreaded
-	 * environment so we must lock all mutexes in the prefork function to
-	 * avoid a situation in which a thread that did not call fork() held a
-	 * lock, making future unlocking impossible. We lock right before
-	 * C_Login().
-	 */
-	if (pubkey_token_flags & CKF_LOGIN_REQUIRED || is_private == CK_TRUE)
-		{
-		if (*login_done == CK_FALSE &&
-		    uri_struct->askpass == NULL)
-			{
-			PK11err(PK11_F_TOKEN_LOGIN,
-			    PK11_R_TOKEN_PIN_NOT_PROVIDED);
-			goto err;
-			}
-
-		if (*login_done == CK_FALSE &&
-		    uri_struct->askpass != NULL)
-			{
-			if (pk11_get_pin(uri_struct->askpass,
-			    &uri_struct->pin) == 0)
-				{
-				PK11err(PK11_F_TOKEN_LOGIN,
-				    PK11_R_TOKEN_PIN_NOT_PROVIDED);
-				goto err;
-				}
-			}
-
-		/*
-		 * Note that what we are logging into is the keystore from
-		 * pubkey_SLOTID because we work with OP_RSA session type here.
-		 * That also means that we can work with only one keystore in
-		 * the engine.
-		 *
-		 * We must make sure we do not try to login more than once.
-		 * Also, see the comment above on locking strategy.
-		 */
-		(void) pthread_mutex_lock(uri_lock);
-		if (*login_done == CK_FALSE)
-			{
-			if ((rv = pFuncList->C_Login(session,
-			    CKU_USER, (CK_UTF8CHAR*)uri_struct->pin,
-			    strlen(uri_struct->pin))) != CKR_OK)
-				{
-				PK11err_add_data(PK11_F_TOKEN_LOGIN,
-				    PK11_R_TOKEN_LOGIN_FAILED, rv);
-				goto err_locked;
-				}
-
-			*login_done = CK_TRUE;
-
-			/*
-			 * Cache the passphrasedialog for possible child (which
-			 * would need to relogin).
-			 */
-			if (passphrasedialog == NULL &&
-			    uri_struct->askpass != NULL)
-				{
-				passphrasedialog =
-				    strdup(uri_struct->askpass);
-
-				if (passphrasedialog == NULL)
-					{
-					PK11err_add_data(PK11_F_TOKEN_LOGIN,
-					    PK11_R_MALLOC_FAILURE, rv);
-					goto err_locked;
-					}
-				}
-
-			/*
-			 * Check the PIN caching policy. Note that user might
-			 * have provided a PIN even when no PIN was required -
-			 * in that case we always remove the PIN from memory.
-			 */
-			if (pk11_get_pin_caching_policy() ==
-			    POLICY_WRONG_VALUE)
-				{
-				PK11err(PK11_F_TOKEN_LOGIN,
-				    PK11_R_PIN_CACHING_POLICY_INVALID);
-				goto err_locked;
-				}
-
-			if (pk11_get_pin_caching_policy() != POLICY_NONE)
-				if (pk11_cache_pin(uri_struct->pin) == 0)
-					goto err_locked;
-			}
-		(void) pthread_mutex_unlock(uri_lock);
-		}
-	else
-		{
-			/*
-			 * If token does not require login we take it as the
-			 * login was done.
-			 */
-			*login_done = CK_TRUE;
-		}
-
-	/*
-	 * If we raced at pk11_get_pin() we must make sure that all threads that
-	 * called pk11_get_pin() will erase the PIN from memory, not just the
-	 * one that called C_Login(). Note that if we were supposed to cache the
-	 * PIN it was already cached by now so filling "uri_struct.pin" with
-	 * zero bytes is always OK since pk11_cache_pin() makes a copy of it.
-	 */
-	if (uri_struct->pin != NULL)
-		memset(uri_struct->pin, 0, strlen(uri_struct->pin));
-
-	return (1);
-
-err_locked:
-	(void) pthread_mutex_unlock(uri_lock);
-err:
-	/* Always get rid of the PIN. */
-	if (uri_struct->pin != NULL)
-		memset(uri_struct->pin, 0, strlen(uri_struct->pin));
-	return (0);
-	}
-
-/*
- * Log in to the keystore in the child if we were logged in in the parent. There
- * are similarities in the code with pk11_token_login() but still it is quite
- * different so we need a separate function for this.
- *
- * Note that this function is called under the locked session mutex when fork is
- * detected. That means that C_Login() will be called from the child just once.
- *
- * Returns:
- *	1 on success
- *	0 on failure
- */
-int
-pk11_token_relogin(CK_SESSION_HANDLE session)
-	{
-	CK_RV rv;
-
-	/*
-	 * We are in the child so check if we should login to the token again.
-	 * Note that it is enough to log in to the token through one session
-	 * only, all already open and all future sessions can access the token
-	 * then.
-	 */
-	if (passphrasedialog != NULL)
-		{
-		char *pin = NULL;
-
-		/* If we cached the PIN then use it. */
-		if (token_pin != NULL)
-			pin = token_pin;
-		else if (pk11_get_pin(passphrasedialog, &pin) == 0)
-			goto err;
-
-		(void) pthread_mutex_lock(uri_lock);
-		if ((rv = pFuncList->C_Login(session, CKU_USER,
-		    (CK_UTF8CHAR_PTR)pin, strlen(pin))) != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_TOKEN_RELOGIN,
-			    PK11_R_TOKEN_LOGIN_FAILED, rv);
-			(void) pthread_mutex_unlock(uri_lock);
-			goto err;
-			}
-		(void) pthread_mutex_unlock(uri_lock);
-
-		/* Forget the PIN now if we did not cache it before. */
-		if (pin != token_pin)
-			{
-			memset(pin, 0, strlen(pin));
-			OPENSSL_free(pin);
-			}
-		}
-
-	return (1);
-err:
-	return (0);
-	}
-
-/*
- * This function forks and runs an external command. It would be nice if we
- * could use popen(3C)/pclose(3C) for that but unfortunately we need to be able
- * to get rid of the PIN from the memory. With p(open|close) function calls we
- * cannot control the stdio's memory used for buffering and our tests showed
- * that the PIN really stays there even after pclose().
- *
- * Returns:
- *	allocated buffer on success
- *	NULL on failure
- */
-static char *
-run_askpass(char *dialog)
-	{
-	pid_t pid;
-	int n, p[2];
-	char *buf = NULL;
-
-	if (pipe(p) == -1)
-		{
-		PK11err(PK11_F_RUN_ASKPASS, PK11_R_PIPE_FAILED);
-		return (NULL);
-		}
-
-	switch (pid = fork())
-		{
-		case -1:
-			PK11err(PK11_F_RUN_ASKPASS, PK11_R_FORK_FAILED);
-			return (NULL);
-		/* child */
-		case 0:
-			/*
-			 * This should make sure that dup2() will not fail on
-			 * file descriptor shortage.
-			 */
-			close(p[0]);
-			(void) dup2(p[1], 1);
-			close(p[1]);
-			/*
-			 * Note that we cannot use PK11err() here since we are
-			 * in the child. However, parent will get read() error
-			 * so do not worry.
-			 */
-			(void) execl(dialog, basename(dialog), NULL);
-			exit(1);
-		/* parent */
-		default:
-			/* +1 is for the terminating '\0' */
-			buf = (char *)OPENSSL_malloc(PK11_MAX_PIN_LEN + 1);
-			if (buf == NULL)
-				{
-				PK11err(PK11_F_RUN_ASKPASS,
-				    PK11_R_MALLOC_FAILURE);
-				return (NULL);
-				}
-
-			close(p[1]);
-			n = read(p[0], buf, PK11_MAX_PIN_LEN);
-			if (n == -1 || n == 0)
-				{
-				PK11err(PK11_F_RUN_ASKPASS,
-				    PK11_R_PIN_NOT_READ_FROM_COMMAND);
-				OPENSSL_free(buf);
-				return (NULL);
-				}
-			buf[n] = '\0';
-
-			(void) waitpid(pid, NULL, 0);
-		}
-
-	return (buf);
-	}
-
-#endif	/* OPENSSL_NO_HW_PK11 */
-#endif	/* OPENSSL_NO_HW */
--- a/components/openssl/openssl-0.9.8-fips-140/engines/pkcs11/e_pk11_uri.h	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- *
- */
-
-/*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    [email protected]
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef	E_PK11_URI_H
-#define	E_PK11_URI_H
-
-#include <security/pkcs11t.h>
-
-/* PKCS#11 URI related prefixes and attributes. */
-#define	PK11_URI_PREFIX		"pkcs11:"
-#define	FILE_URI_PREFIX		"file://"
-#define	PK11_TOKEN		"token"
-#define	PK11_MANUF		"manuf"
-#define	PK11_SERIAL		"serial"
-#define	PK11_MODEL		"model"
-#define	PK11_OBJECT		"object"
-#define	PK11_OBJECTTYPE		"objecttype"
-#define	PK11_ASKPASS		"passphrasedialog"
-
-/* PIN caching policy. */
-#define	POLICY_NOT_INITIALIZED	0
-#define	POLICY_NONE		1
-#define	POLICY_MEMORY		2
-#define	POLICY_MLOCKED_MEMORY	3
-#define	POLICY_WRONG_VALUE	4
-
-/*
- * That's what getpassphrase(3c) supports.
- */
-#define	PK11_MAX_PIN_LEN	256
-
-/* Add new attributes of the PKCS#11 URI here. */
-typedef struct pkcs11_uri_struct {
-	char	*object;	/* object label, the only mandatory info */
-	char	*objecttype;	/* (private|public|cert), currently unused */
-	char	*token;		/* token label */
-	char	*manuf;		/* manufacturer label */
-	char	*serial;	/* serial number label */
-	char	*model;		/* model label */
-	char	*askpass;	/* full path to the command to get the PIN */
-	/* Not part of the PKCS11 URI itself. */
-	char	*pin;		/* token PIN */
-} pkcs11_uri;
-
-/* For URI processing. */
-extern pthread_mutex_t *uri_lock;
-
-int pk11_get_pin(char *dialog, char **pin);
-int pk11_get_pin_caching_policy(void);
-int pk11_process_pkcs11_uri(const char *uristr, pkcs11_uri *uri_struct,
-	const char **file);
-int pk11_check_token_attrs(pkcs11_uri *uri_struct);
-void pk11_free_pkcs11_uri(pkcs11_uri *uri_struct, CK_BBOOL free_uri_itself);
-int pk11_cache_pin(char *pin);
-int pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
-	pkcs11_uri *uri_struct, CK_BBOOL is_private);
-int pk11_token_relogin(CK_SESSION_HANDLE session);
-
-#endif /* E_PK11_URI_H */
--- a/components/openssl/openssl-0.9.8-fips-140/llib-lcrypto	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* LINTLIBRARY */
-/* PROTOLIB1 */
-
-#include <openssl/asn1.h>
-#include <openssl/asn1_mac.h>
-#include <openssl/bio.h>
-#include <openssl/blowfish.h>
-#include <openssl/bn.h>
-#include <openssl/buffer.h>
-#include <openssl/comp.h>
-#include <openssl/conf.h>
-#include <openssl/conf_api.h>
-#include <openssl/crypto.h>
-#include <openssl/des.h>
-#include <openssl/dh.h>
-#include <openssl/dsa.h>
-#include <openssl/dso.h>
-#include <openssl/e_os2.h>
-#include <openssl/ebcdic.h>
-#include <openssl/engine.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#include <openssl/lhash.h>
-#include <openssl/obj_mac.h>
-#include <openssl/objects.h>
-#include <openssl/opensslconf.h>
-#include <openssl/opensslv.h>
-#include <openssl/pem.h>
-#include <openssl/pem2.h>
-#include <openssl/pkcs12.h>
-#include <openssl/pkcs7.h>
-#include <openssl/rand.h>
-#include <openssl/rsa.h>
-#include <openssl/safestack.h>
-#include <openssl/sha.h>
-#include <openssl/stack.h>
-#include <openssl/symhacks.h>
-#include <openssl/tmdiff.h>
-#include <openssl/txt_db.h>
-#include <openssl/x509.h>
-#include <openssl/x509_vfy.h>
-#include <openssl/x509v3.h>
--- a/components/openssl/openssl-0.9.8-fips-140/llib-lssl	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* LINTLIBRARY */
-/* PROTOLIB1 */
-
-#include <openssl/ssl.h>
-#include <openssl/ssl2.h>
-#include <openssl/ssl23.h>
-#include <openssl/ssl3.h>
--- a/components/openssl/openssl-0.9.8-fips-140/openssl-0.9.8-fips-140.license	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-
-  LICENSE ISSUES
-  ==============
-
-  The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
-  the OpenSSL License and the original SSLeay license apply to the toolkit.
-  See below for the actual license texts. Actually both licenses are BSD-style
-  Open Source licenses. In case of any license issues related to OpenSSL
-  please contact [email protected]
-
-  OpenSSL License
-  ---------------
-
-/* ====================================================================
- * Copyright (c) 1998-2008 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    [email protected]
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
- Original SSLeay License
- -----------------------
-
-/* Copyright (C) 1995-1998 Eric Young ([email protected])
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young ([email protected]).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson ([email protected]).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young ([email protected])"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson ([email protected])"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
--- a/components/openssl/openssl-0.9.8-fips-140/openssl-0.9.8-fips-140.p5m	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
-#
-
-<transform file path=usr.*/man/.+ -> default mangler.man.stability uncommitted>
-set name=pkg.fmri \
-    value=pkg:/library/security/openssl/[email protected]$(IPS_COMPONENT_VERSION),$(BUILD_VERSION)
-set name=pkg.human-version value=$(COMPONENT_VERSION)
-set name=pkg.summary value="FIPS 140-2 Capable OpenSSL libraries"
-set name=com.oracle.info.tpno value=13019
-set name=com.oracle.info.description value="the FIPS 140-2 Capable OpenSSL libraries"
-set name=info.classification \
-    value="org.opensolaris.category.2008:System/Security"
-set name=info.source-url value=$(COMPONENT_ARCHIVE_URL)
-set name=info.upstream-url value=$(COMPONENT_PROJECT_URL)
-set name=org.opensolaris.arc-caseid \
-    value=PSARC/2009/507
-set name=org.opensolaris.consolidation value=$(CONSOLIDATION)
-# Basic directories and a configuration file.
-dir path=etc
-dir path=etc/openssl group=sys
-dir path=etc/openssl/fips-140 group=sys
-file etc/openssl/openssl.cnf path=etc/openssl/fips-140/openssl.cnf group=sys mode=0644 preserve=true
-dir path=lib
-dir path=lib/openssl
-dir path=lib/openssl/fips-140
-dir path=lib/openssl/fips-140/$(MACH64)
-dir path=usr
-dir path=usr/include
-dir path=usr/include/openssl
-dir path=usr/include/openssl/fips-140
-dir path=usr/include/openssl/fips-140/openssl
-link path=lib/openssl/fips-140/64 target=$(MACH64)
-# 32 bit libraries, lint libraries, and engines.
-file $(MACH32)/libcrypto.so.0.9.8 path=lib/openssl/fips-140/libcrypto.so.0.9.8
-link path=lib/openssl/fips-140/libcrypto.so target=libcrypto.so.0.9.8
-file $(MACH32)/libssl.so.0.9.8 path=lib/openssl/fips-140/libssl.so.0.9.8
-link path=lib/openssl/fips-140/libssl.so target=libssl.so.0.9.8
-file llib-lcrypto path=lib/openssl/fips-140/llib-lcrypto
-file $(MACH32)/llib-lcrypto.ln path=lib/openssl/fips-140/llib-lcrypto.ln
-file llib-lssl path=lib/openssl/fips-140/llib-lssl
-file $(MACH32)/llib-lssl.ln path=lib/openssl/fips-140/llib-lssl.ln
-file $(MACH32)/engines/libpk11.so path=lib/openssl/fips-140/engines/libpk11.so.1
-link path=lib/openssl/fips-140/engines/libpk11.so target=libpk11.so.1
-# 64 bit libraries, lint libraries, and engines.
-file $(MACH64)/libcrypto.so.0.9.8 path=lib/openssl/fips-140/$(MACH64)/libcrypto.so.0.9.8
-link path=lib/openssl/fips-140/$(MACH64)/libcrypto.so target=libcrypto.so.0.9.8
-file $(MACH64)/libssl.so.0.9.8 path=lib/openssl/fips-140/$(MACH64)/libssl.so.0.9.8
-link path=lib/openssl/fips-140/$(MACH64)/libssl.so target=libssl.so.0.9.8
-file llib-lcrypto path=lib/openssl/fips-140/$(MACH64)/llib-lcrypto
-file $(MACH64)/llib-lcrypto.ln path=lib/openssl/fips-140/$(MACH64)/llib-lcrypto.ln
-file llib-lssl path=lib/openssl/fips-140/$(MACH64)/llib-lssl
-file $(MACH64)/llib-lssl.ln path=lib/openssl/fips-140/$(MACH64)/llib-lssl.ln
-file $(MACH64)/engines/libpk11.so path=lib/openssl/fips-140/engines/$(MACH64)/libpk11.so.1
-link path=lib/openssl/fips-140/engines/$(MACH64)/libpk11.so target=libpk11.so.1
-# Header files.
-#
-# Take header files from the 32-bit build. This build has the patched
-# opensslconf.h (64-bit build does not). We cannot take header files from the
-# proto area since it could contain headers installed for the 64-bit build.
-<transform file path=usr/include/openssl/fips-140/openssl/(.+\.h)$ -> \
-    set action.hash $(MACH32)/include/openssl/%<1> >
-file path=usr/include/openssl/fips-140/openssl/aes.h
-file path=usr/include/openssl/fips-140/openssl/asn1.h
-file path=usr/include/openssl/fips-140/openssl/asn1_mac.h
-file path=usr/include/openssl/fips-140/openssl/asn1t.h
-file path=usr/include/openssl/fips-140/openssl/bio.h
-file path=usr/include/openssl/fips-140/openssl/blowfish.h
-file path=usr/include/openssl/fips-140/openssl/bn.h
-file path=usr/include/openssl/fips-140/openssl/buffer.h
-file path=usr/include/openssl/fips-140/openssl/cast.h
-file path=usr/include/openssl/fips-140/openssl/comp.h
-file path=usr/include/openssl/fips-140/openssl/conf.h
-file path=usr/include/openssl/fips-140/openssl/conf_api.h
-file path=usr/include/openssl/fips-140/openssl/crypto.h
-file path=usr/include/openssl/fips-140/openssl/des.h
-file path=usr/include/openssl/fips-140/openssl/des_old.h
-file path=usr/include/openssl/fips-140/openssl/dh.h
-file path=usr/include/openssl/fips-140/openssl/dsa.h
-file path=usr/include/openssl/fips-140/openssl/dso.h
-file path=usr/include/openssl/fips-140/openssl/dtls1.h
-file path=usr/include/openssl/fips-140/openssl/e_os2.h
-file path=usr/include/openssl/fips-140/openssl/ebcdic.h
-file path=usr/include/openssl/fips-140/openssl/engine.h
-file path=usr/include/openssl/fips-140/openssl/err.h
-file path=usr/include/openssl/fips-140/openssl/evp.h
-file path=usr/include/openssl/fips-140/openssl/fips.h
-file path=usr/include/openssl/fips-140/openssl/fips_rand.h
-file path=usr/include/openssl/fips-140/openssl/hmac.h
-file path=usr/include/openssl/fips-140/openssl/krb5_asn.h
-file path=usr/include/openssl/fips-140/openssl/kssl.h
-file path=usr/include/openssl/fips-140/openssl/lhash.h
-file path=usr/include/openssl/fips-140/openssl/md2.h
-file path=usr/include/openssl/fips-140/openssl/md4.h
-file path=usr/include/openssl/fips-140/openssl/md5.h
-file path=usr/include/openssl/fips-140/openssl/obj_mac.h
-file path=usr/include/openssl/fips-140/openssl/objects.h
-file path=usr/include/openssl/fips-140/openssl/ocsp.h
-file path=usr/include/openssl/fips-140/openssl/opensslconf.h
-file path=usr/include/openssl/fips-140/openssl/opensslv.h
-file path=usr/include/openssl/fips-140/openssl/ossl_typ.h
-file path=usr/include/openssl/fips-140/openssl/pem.h
-file path=usr/include/openssl/fips-140/openssl/pem2.h
-file path=usr/include/openssl/fips-140/openssl/pkcs12.h
-file path=usr/include/openssl/fips-140/openssl/pkcs7.h
-file path=usr/include/openssl/fips-140/openssl/pq_compat.h
-file path=usr/include/openssl/fips-140/openssl/pqueue.h
-file path=usr/include/openssl/fips-140/openssl/rand.h
-file path=usr/include/openssl/fips-140/openssl/rc2.h
-file path=usr/include/openssl/fips-140/openssl/rc4.h
-file path=usr/include/openssl/fips-140/openssl/ripemd.h
-file path=usr/include/openssl/fips-140/openssl/rsa.h
-file path=usr/include/openssl/fips-140/openssl/safestack.h
-file path=usr/include/openssl/fips-140/openssl/sha.h
-file path=usr/include/openssl/fips-140/openssl/ssl.h
-file path=usr/include/openssl/fips-140/openssl/ssl2.h
-file path=usr/include/openssl/fips-140/openssl/ssl23.h
-file path=usr/include/openssl/fips-140/openssl/ssl3.h
-file path=usr/include/openssl/fips-140/openssl/stack.h
-file path=usr/include/openssl/fips-140/openssl/store.h
-file path=usr/include/openssl/fips-140/openssl/symhacks.h
-file path=usr/include/openssl/fips-140/openssl/tls1.h
-file path=usr/include/openssl/fips-140/openssl/tmdiff.h
-file path=usr/include/openssl/fips-140/openssl/txt_db.h
-file path=usr/include/openssl/fips-140/openssl/ui.h
-file path=usr/include/openssl/fips-140/openssl/ui_compat.h
-file path=usr/include/openssl/fips-140/openssl/x509.h
-file path=usr/include/openssl/fips-140/openssl/x509_vfy.h
-file path=usr/include/openssl/fips-140/openssl/x509v3.h
-license openssl-0.9.8-fips-140.license license="OpenSSL, SSLeay"
--- a/components/openssl/openssl-0.9.8-fips-140/patches-post-config/opensslconf.patch	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
---- /tmp/opensslconf.h	Thu Mar 10 06:46:57 2011
-+++ /tmp/opensslconf.h.new	Thu Mar 10 06:47:41 2011
[email protected]@ -2,6 +2,12 @@
- /* WARNING: Generated automatically from opensslconf.h.in by Configure. */
- 
- /* OpenSSL was configured with the following options: */
-+#if defined(__sparcv9)
-+#ifndef OPENSSL_SYSNAME_ULTRASPARC                 
-+# define OPENSSL_SYSNAME_ULTRASPARC                
-+#endif   
-+#endif
-+
- #ifndef OPENSSL_DOING_MAKEDEPEND
- 
- 
[email protected]@ -205,10 +211,14 @@
- 
- #if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
- #if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
-+#if defined(__sparcv9) || defined(__x86_64)
-+#define ENGINESDIR "/lib/openssl/engines/64"
-+#else
- #define ENGINESDIR "/lib/openssl/engines"
--#define OPENSSLDIR "/etc/openssl"
- #endif
-+#define OPENSSLDIR "/etc/openssl/fips-140"
- #endif
-+#endif
- 
- #undef OPENSSL_UNISTD
- #define OPENSSL_UNISTD <unistd.h>
[email protected]@ -252,13 +262,21 @@
- /* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
-  * %20 speed up (longs are 8 bytes, int's are 4). */
- #ifndef DES_LONG
-+#if defined(__sparcv9) || defined(__x86_64)
-+#define DES_LONG unsigned int
-+#else
- #define DES_LONG unsigned long
- #endif
- #endif
-+#endif
- 
- #if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
- #define CONFIG_HEADER_BN_H
-+#if defined(__sparcv9) || defined(__x86_64)
-+#undef BN_LLONG
-+#else
- #define BN_LLONG
-+#endif
- 
- /* Should we define BN_DIV2W here? */
- 
[email protected]@ -266,9 +284,14 @@
- /* The prime number generation stuff may not work when
-  * EIGHT_BIT but I don't care since I've only used this mode
-  * for debuging the bignum libraries */
-+#if defined(__sparcv9) || defined(__x86_64)
-+#define SIXTY_FOUR_BIT_LONG
-+#undef THIRTY_TWO_BIT
-+#else
- #undef SIXTY_FOUR_BIT_LONG
--#undef SIXTY_FOUR_BIT
- #define THIRTY_TWO_BIT
-+#endif
-+#undef SIXTY_FOUR_BIT
- #undef SIXTEEN_BIT
- #undef EIGHT_BIT
- #endif
--- a/components/openssl/openssl-0.9.8-fips-140/patches/08-6193522.patch	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-diff -ruN openssl-0.9.8a/apps/CA.pl.in openssl-0.9.8a/apps/CA.pl.in
---- openssl-0.9.8a/apps/CA.pl.in	2005-07-04 23:44:22.000000000 +0200
-+++ openssl-0.9.8a/apps/CA.pl.in	2009-04-21 16:08:45.354925289 +0200
[email protected]@ -53,7 +53,7 @@
- $X509="$openssl x509";
- $PKCS12="$openssl pkcs12";
- 
--$CATOP="./demoCA";
-+$CATOP="/etc/openssl";
- $CAKEY="cakey.pem";
- $CAREQ="careq.pem";
- $CACERT="cacert.pem";
-diff -ruN openssl-0.9.8a/apps/openssl.cnf openssl-0.9.8a/apps/openssl.cnf
---- openssl-0.9.8a/apps/openssl.cnf	2005-09-16 14:20:24.000000000 +0200
-+++ openssl-0.9.8a/apps/openssl.cnf	2009-04-21 16:07:13.910980196 +0200
[email protected]@ -34,7 +34,7 @@
- ####################################################################
- [ CA_default ]
- 
--dir		= ./demoCA		# Where everything is kept
-+dir		= /etc/openssl		# Where everything is kept
- certs		= $dir/certs		# Where the issued certs are kept
- crl_dir		= $dir/crl		# Where the issued crl are kept
- database	= $dir/index.txt	# database index file.
[email protected]@ -44,7 +44,7 @@
- 
- certificate	= $dir/cacert.pem 	# The CA certificate
- serial		= $dir/serial 		# The current serial number
--crlnumber	= $dir/crlnumber	# the current crl number
-+#crlnumber	= $dir/crlnumber	# the current crl number
- 					# must be commented out to leave a V1 CRL
- crl		= $dir/crl.pem 		# The current CRL
- private_key	= $dir/private/cakey.pem# The private key
[email protected]@ -122,17 +122,17 @@
- 
- [ req_distinguished_name ]
- countryName			= Country Name (2 letter code)
--countryName_default		= AU
-+#countryName_default		= US
- countryName_min			= 2
- countryName_max			= 2
- 
- stateOrProvinceName		= State or Province Name (full name)
--stateOrProvinceName_default	= Some-State
-+#stateOrProvinceName_default	= Some-State
- 
- localityName			= Locality Name (eg, city)
- 
- 0.organizationName		= Organization Name (eg, company)
--0.organizationName_default	= Internet Widgits Pty Ltd
-+#0.organizationName_default	= Unconfigured OpenSSL Installation
- 
- # we can do this but it is not needed normally :-)
- #1.organizationName		= Second Organization Name (eg, company)
--- a/components/openssl/openssl-0.9.8-fips-140/patches/11-6546806.patch	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-diff -ruN openssl-0.9.8a/doc/crypto/hmac.pod openssl-0.9.8a/doc/crypto/hmac.pod
---- openssl-0.9.8a/doc/crypto/hmac.pod	2002-07-18 20:54:45.000000000 +0200
-+++ openssl-0.9.8a/doc/crypto/hmac.pod	2009-04-10 11:09:46.449071541 +0200
[email protected]@ -2,7 +2,7 @@
- 
- =head1 NAME
- 
--HMAC, HMAC_Init, HMAC_Update, HMAC_Final, HMAC_cleanup - HMAC message
-+HMAC, HMAC_CTX_init, HMAC_Init, HMAC_Init_ex, HMAC_Update, HMAC_Final, HMAC_CTX_cleanup, HMAC_cleanup - HMAC message
- authentication code
- 
- =head1 SYNOPSIS
--- a/components/openssl/openssl-0.9.8-fips-140/patches/15-pkcs11_engine-0.9.8a.patch	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,208 +0,0 @@
-diff -ruN ../a/openssl-0.9.8o/Configure openssl-0.9.8o/Configure
---- ../a/openssl-0.9.8o/Configure	2010-05-20 10:36:23.000000000 -0700
-+++ openssl-0.9.8o/Configure	2010-09-22 18:32:18.922795700 -0700
[email protected]@ -12,7 +12,7 @@
- 
- # see INSTALL for instructions.
- 
--my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [enable-montasm] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
-+my $usage="Usage: Configure --pk11-libname=PK11_LIB_LOCATION [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [enable-montasm] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
- 
- # Options:
- #
[email protected]@ -21,6 +21,9 @@
- # --prefix      prefix for the OpenSSL include, lib and bin directories
- #               (Default: the OPENSSLDIR directory)
- #
-+# --pk11-libname  PKCS#11 library name.
-+#               (Default: none)
-+#
- # --install_prefix  Additional prefix for package builders (empty by
- #               default).  This needn't be set in advance, you can
- #               just as well use "make INSTALL_PREFIX=/whatever install".
[email protected]@ -587,6 +590,9 @@
- my $idx_ranlib = $idx++;
- my $idx_arflags = $idx++;
- 
-+# PKCS#11 engine patch
-+my $pk11_libname="";
-+
- my $prefix="";
- my $libdir="";
- my $openssldir="";
[email protected]@ -825,6 +831,10 @@
- 				{
- 				$flags.=$_." ";
- 				}
-+                        elsif (/^--pk11-libname=(.*)$/)
-+                                {
-+                                $pk11_libname=$1;
-+                                }
- 			elsif (/^--prefix=(.*)$/)
- 				{
- 				$prefix=$1;
[email protected]@ -960,6 +970,13 @@
- 	exit 0;
- }
- 
-+if (! $pk11_libname)
-+        {
-+        print STDERR "You must set --pk11-libname for PKCS#11 library.\n";
-+        print STDERR "See README.pkcs11 for more information.\n";
-+        exit 1;
-+        }
-+
- if ($target =~ m/^CygWin32(-.*)$/) {
- 	$target = "Cygwin".$1;
- }
[email protected]@ -1126,6 +1143,8 @@
- if ($flags ne "")	{ $cflags="$flags$cflags"; }
- else			{ $no_user_cflags=1;       }
- 
-+$cflags="-DPK11_LIB_LOCATION=\"$pk11_libname\" $cflags";
-+
- # Kerberos settings.  The flavor must be provided from outside, either through
- # the script "config" or manually.
- if (!$no_krb5)
[email protected]@ -1489,6 +1508,7 @@
- 	s/^VERSION=.*/VERSION=$version/;
- 	s/^MAJOR=.*/MAJOR=$major/;
- 	s/^MINOR=.*/MINOR=$minor/;
-+	s/^PK11_LIB_LOCATION=.*/PK11_LIB_LOCATION=$pk11_libname/;
- 	s/^SHLIB_VERSION_NUMBER=.*/SHLIB_VERSION_NUMBER=$shlib_version_number/;
- 	s/^SHLIB_VERSION_HISTORY=.*/SHLIB_VERSION_HISTORY=$shlib_version_history/;
-	s/^SHLIB_MAJOR=.*/SHLIB_MAJOR=$shlib_major/;
-diff -ruN ../a/openssl-0.9.8o/Makefile.org openssl-0.9.8o/Makefile.org
---- ../a/openssl-0.9.8o/Makefile.org	2010-01-27 08:06:36.000000000 -0800
-+++ openssl-0.9.8o/Makefile.org	2010-09-22 18:32:19.152576100 -0700
[email protected]@ -26,6 +26,9 @@
- INSTALL_PREFIX=
- INSTALLTOP=/usr/local/ssl
- 
-+# You must set this through --pk11-libname configure option.
-+PK11_LIB_LOCATION=
-+
- # Do not edit this manually. Use Configure --openssldir=DIR do change this!
- OPENSSLDIR=/usr/local/ssl
- 
---- openssl-0.9.8y/engines/Makefile.~1~ Wed Jan  8 14:07:33 2014
-+++ openssl-0.9.8y/engines/Makefile     Wed Jan  8 13:51:03 2014
[email protected]@ -20,7 +20,8 @@
- APPS=
- 
- LIB=$(TOP)/libcrypto.a
--LIBNAMES= 4758cca aep atalla cswift gmp chil nuron sureware ubsec capi
-+LIBNAMES= 4758cca aep atalla cswift gmp chil nuron sureware ubsec capi \
-+	pk11
- 
- LIBSRC=	e_4758cca.c \
- 	e_aep.c \
[email protected]@ -31,7 +32,8 @@
-	e_nuron.c \
-	e_sureware.c \
-	e_ubsec.c \
--	e_capi.c
-+	e_capi.c \
-+	e_pk11.c
- LIBOBJ= e_4758cca.o \
-	e_aep.o \
-	e_atalla.o \
[email protected]@ -41,7 +43,8 @@
-	e_nuron.o \
-	e_sureware.o \
-	e_ubsec.o \
--	e_capi.o
-+	e_capi.o \
-+	e_pk11.o
- 
- SRC= $(LIBSRC)
- 
[email protected]@ -55,7 +58,8 @@
-	e_nuron_err.c e_nuron_err.h \
-	e_sureware_err.c e_sureware_err.h \
-	e_ubsec_err.c e_ubsec_err.h \
--	e_capi_err.c e_capi_err.h
-+	e_capi_err.c e_capi_err.h \
-+	e_pk11.h e_pk11_uri.h e_pk11_err.h e_pk11_pub.c e_pk11_uri.c e_pk11_err.c
- 
- ALL=    $(GENERAL) $(SRC) $(HEADER)
- 
[email protected]@ -70,7 +74,7 @@
-		for l in $(LIBNAMES); do \
-			$(MAKE) -f ../Makefile.shared -e \
-				LIBNAME=$$l LIBEXTRAS=e_$$l.o \
--				LIBDEPS='-L.. -lcrypto $(EX_LIBS)' \
-+				LIBDEPS='-L.. -lcrypto -lcryptoutil $(EX_LIBS)' \
-				link_o.$(SHLIB_TARGET); \
-		done; \
-	else \
---- openssl-0.9.8y/crypto/engine/eng_all.c.~1~  Tue Feb  5 03:58:59 2013
-+++ openssl-0.9.8y/crypto/engine/eng_all.c      Wed Jan  8 14:24:35 2014
[email protected]@ -59,6 +59,16 @@
- #include "cryptlib.h"
- #include "eng_int.h"
- 
-+/*
-+ * pkcs11 engine is no longer a build-in engine, and ENGINE_load_pk11() needs to be
-+ * defined in libcrypto.so for ssh. Instead of load pkcs11 engine, it loads dynamic
-+ * engines.
-+ */
-+void ENGINE_load_pk11(void)
-+	{
-+	ENGINE_load_dynamic();
-+	}
-+
- void ENGINE_load_builtin_engines(void)
-	{
-	/* There's no longer any need for an "openssl" ENGINE unless, one day,
[email protected]@ -72,6 +82,9 @@
-	ENGINE_load_padlock();
- #endif
-	ENGINE_load_dynamic();
-+#ifndef OPENSSL_NO_HW_PKCS11
-+	ENGINE_load_pk11();
-+#endif
- #ifndef OPENSSL_NO_STATIC_ENGINE
- #ifndef OPENSSL_NO_HW
- #ifndef OPENSSL_NO_HW_4758_CCA
-
---- openssl-0.9.8y/crypto/dso/dso_lib.c.~1~     Wed Jan  8 15:16:36 2014
-+++ openssl-0.9.8y/crypto/dso/dso_lib.c Wed Jan  8 15:22:18 2014
[email protected]@ -433,6 +433,26 @@
-		DSOerr(DSO_F_DSO_CONVERT_FILENAME,DSO_R_NO_FILENAME);
-		return(NULL);
-		}
-+/*
-+ * For pkcs11 engine, use libpk11.so (instead of libpkcs11.so) to
-+ * avoid the name collision with PKCS#11 library.
-+ */
-+	if (strcmp(filename, "pkcs11") == 0)
-+		{
-+#ifdef _LP64
-+		static const char fullpath[] = "/lib/openssl/engines/64/libpk11.so";
-+#else
-+		static const char fullpath[] = "/lib/openssl/engines/libpk11.so";
-+#endif
-+		result = OPENSSL_malloc(strlen(fullpath) + 1);
-+		if (result == NULL)
-+			{
-+			DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_MALLOC_FAILURE);
-+			return(NULL);
-+			}
-+		BUF_strlcpy(result, fullpath, sizeof(fullpath));
-+		return(result);
-+		}
-	if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0)
-		{
-		if(dso->name_converter != NULL)
-diff -ruN ../a/openssl-0.9.8o/crypto/engine/engine.h openssl-0.9.8o/crypto/engine/engine.h
---- ../a/openssl-0.9.8o/crypto/engine/engine.h	2010-02-09 06:18:15.000000000 -0800
-+++ openssl-0.9.8o/crypto/engine/engine.h	2010-09-22 18:32:19.063758100 -0700
[email protected]@ -337,6 +337,7 @@
- void ENGINE_load_ubsec(void);
- #endif
- void ENGINE_load_cryptodev(void);
-+void ENGINE_load_pk11(void);
- void ENGINE_load_padlock(void);
- void ENGINE_load_builtin_engines(void);
- #ifdef OPENSSL_SYS_WIN32
--- a/components/openssl/openssl-0.9.8-fips-140/patches/18-compiler_opts.patch	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-diff -ruN openssl-0.9.8k/Configure openssl-0.9.8k/Configure
---- openssl-0.9.8k/Configure	2009-02-16 09:44:22.000000000 +0100
-+++ openssl-0.9.8k/Configure	2009-06-25 16:19:22.897811727 +0200
[email protected]@ -130,6 +130,11 @@
- my $x86_64_asm="x86_64cpuid.o:x86_64-gcc.o x86_64-mont.o::aes-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o::rc4-x86_64.o::";
- my $ia64_asm=":bn-ia64.o::aes_core.o aes_cbc.o aes-ia64.o:::sha1-ia64.o sha256-ia64.o sha512-ia64.o::rc4-ia64.o rc4_skey.o::";
- 
-+# ASM without "rx86-elf.o rc4_skey.o". The current RC4 asm assumes RC4_INT. Solaris/OpenSolaris uses RC4_CHAR.
-+# Changing to RC4_INT would break ABI compatibility.
-+my $x86_elf_asm_sunw="x86cpuid-elf.o:bn86-elf.o co86-elf.o MAYBE-MO86-elf.o:dx86-elf.o yx86-elf.o:ax86-elf.o:bx86-elf.o:mx86-elf.o:sx86-elf.o s512sse2-elf.o:cx86-elf.o::rm86-elf.o:r586-elf.o";
-+my $x86_64_asm_sunw="x86_64cpuid.o:x86_64-gcc.o x86_64-mont.o::aes-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o::::";
-+
- my $no_asm="::::::::::";
- 
- # As for $BSDthreads. Idea is to maintain "collective" set of flags,
[email protected]@ -235,6 +240,12 @@
- #"sunos-cc", "cc:-O4 -DNOPROTO -DNOCONST::(unknown):SUNOS::DES_UNROLL:${no_asm}::",
- "sunos-gcc","gcc:-O3 -mv8 -Dssize_t=int::(unknown):SUNOS::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL DES_PTR DES_RISC1:${no_asm}::",
- 
-+#### Solaris configs, used for OpenSSL as delivered by OpenSolaris
-+"solaris-x86-cc-sunw","cc:-m32 -xO3 -xspace -g -Xa::-D_REENTRANT::-lsocket -lnsl -lc -R /lib/openssl/fips-140:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_UNROLL BF_PTR:${x86_elf_asm_sunw}:dlfcn:solaris-shared:-KPIC:-m32 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign -M/usr/lib/ld/map.noexdata:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-+"solaris64-x86_64-cc-sunw","cc:-xO3 -m64 -g -xstrconst -Xa -DL_ENDIAN::-D_REENTRANT::-lsocket -lnsl -lc -R /lib/openssl/fips-140/64:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK BF_PTR DES_PTR DES_INT DES_UNROLL:${x86_64_asm_sunw}:dlfcn:solaris-shared:-KPIC:-m64 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign -M/usr/lib/ld/map.noexdata:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-+"solaris-sparcv8-cc-sunw","cc:-m32 -Qoption cg -xregs=no%appl -xO5 -g -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -lc -R /lib/openssl/fips-140:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR::sparcv8plus.o::::::::::dlfcn:solaris-shared:-KPIC:-m32 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-+"solaris64-sparcv9-cc-sunw","cc:-m64 -Qoption cg -xregs=no%appl -xO5 -g -xstrconst -xdepend -xspace -Xa -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -lc -R /lib/openssl/fips-140/64:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR::::::::::::dlfcn:solaris-shared:-KPIC:-m64 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):/usr/ccs/bin/ar rs",
-+
- #### IRIX 5.x configs
- # -mips2 flag is added by ./config when appropriate.
- "irix-gcc","gcc:-O3 -DTERMIOS -DB_ENDIAN::(unknown):::BN_LLONG MD2_CHAR RC4_INDEX RC4_CHAR RC4_CHUNK DES_UNROLL DES_RISC2 DES_PTR BF_PTR:${no_asm}:dlfcn:irix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
--- a/components/openssl/openssl-0.9.8-fips-140/patches/20-remove_rpath.patch	Mon Jan 27 23:00:15 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-diff -ruN openssl-0.9.8a/Makefile.shared openssl-0.9.8a/Makefile.shared
---- openssl-0.9.8a/Makefile.shared	2005-06-23 22:47:54.000000000 +0200
-+++ openssl-0.9.8a/Makefile.shared	2009-05-20 00:35:52.611961155 +0200
[email protected]@ -340,7 +340,7 @@
- 	@ if ${DETECT_GNU_LD}; then \
- 		$(DO_GNU_APP); \
</