# HG changeset patch # User Misaki Miyashita # Date 1440785092 25200 # Node ID 1fb8a14c6702fa27bfd1fda0074f94c4f7bf5a96 # Parent 54dafbe33fdbf78a77572dfa0776891d8251fe6d PSARC/2015/353 OpenSSL 1.0.2 20829622 Upgrade to OpenSSL 1.0.2d diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/README --- a/components/openssl/README Fri Aug 28 07:46:44 2015 -0700 +++ b/components/openssl/README Fri Aug 28 11:04:52 2015 -0700 @@ -25,34 +25,17 @@ Build Layout --- -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 +OpenSSL build is run four times. Once for regular dynamic non-fips, once +for static bits to link with standalone wanboot binary, once for fips-140, +and once for FIPS-140 canister (in the openssl-fips component) +needed to build 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 built on sparc. See also comments in all the Makefiles for more information. OpenSSL Version ---- - -For non-FIPS build, we currently deliver OpenSSL 1.0.1 with some updates -from OpenSSL 1.0.2 to make T4 instructions embedded in the OpenSSL -upstream code. As of April 2013, 1.0.2 is not yet released, and therefore, -we have decided to patch the code. -The following files/code are copied in from 1.0.2. -added: - components/openssl/openssl-1.0.1/inline-t4/aest4-sparcv9.pl - components/openssl/openssl-1.0.1/inline-t4/dest4-sparcv9.pl - components/openssl/openssl-1.0.1/inline-t4/md5-sparcv9.pl - components/openssl/openssl-1.0.1/inline-t4/sparc_arch.h - components/openssl/openssl-1.0.1/inline-t4/sparct4-mont.pl - components/openssl/openssl-1.0.1/inline-t4/sparcv9_modes.pl - components/openssl/openssl-1.0.1/inline-t4/sparcv9-gf2m.pl - components/openssl/openssl-1.0.1/inline-t4/vis3-mont.pl - components/openssl/openssl-1.0.1/patches/openssl-t4-inline.sparc-patch - +-------------- The non-fips Build. --- @@ -64,7 +47,7 @@ The fips Build --- -We are now shipping FIPS-140 certified OpenSSL 1.0.1 with S12 and S11.2. +We are now shipping FIPS-140 certified OpenSSL with S11.2 and later. The admin may choose to activate 'openssl-fips' implementation using 'pkg mediator'. The wanboot Build @@ -97,7 +80,7 @@ first build static standalone openssl bits in Userland. As a site effect, static libraries libssl.a and libcrypto.a are created in build/sparcv9-wanboot. - $ cd $USERLAND/components/openssl/openssl-1.0.1 ; gmake build + $ cd $USERLAND/components/openssl/openssl-default ; gmake build Next, collect some information from linking wanboot static libraries in ON. This can be done by the following hack. @@ -105,16 +88,16 @@ $ cd $ON/usr/src/psm/stand/boot/sparcv9/sun4 $ touch wanboot.o $ LD_OPTIONS="-Dfiles,symbols,output=ld.dbg \ - -L$USERLAND/components/openssl/openssl-1.0.1/build/sparcv9-wanboot " \ + -L$USERLAND/components/openssl/openssl-default/build/sparcv9-wanboot " \ WAN_OPENSSL=" -lwanboot -lssl -lcrypto" dmake all The following sort of information ends up in ld.dbg (note that the debugging output from the link-editor is not considered a 'stable interface' and may change in the future): - debug: file=/builds/tkuthan/ul-wanboot-rebuilt/components/openssl/openssl-1.0.1/build/sparcv9-wanboot/libcrypto.a(sparcv9cap.o) [ ET_REL ] + debug: file=/builds/tkuthan/ul-wanboot-rebuilt/components/openssl/openssl-default/build/sparcv9-wanboot/libcrypto.a(sparcv9cap.o) [ ET_REL ] debug: - debug: symbol table processing; file=/builds/tkuthan/ul-wanboot-rebuilt/components/openssl/openssl-1.0.1/build/sparcv9-wanboot/libcrypto.a(sparcv9cap.o) [ ET_REL ] + debug: symbol table processing; file=/builds/tkuthan/ul-wanboot-rebuilt/components/openssl/openssl-default/build/sparcv9-wanboot/libcrypto.a(sparcv9cap.o) [ ET_REL ] debug: symbol[1]=sparcv9cap.c .... @@ -126,7 +109,7 @@ USERLAND=/builds/tkuthan/ul-wanboot-rebuilt ON=/builds/tkuthan/on11u1-wanboot-rti - BUILD=$USERLAND/components/openssl/openssl-1.0.1/build/sparcv9-wanboot + BUILD=$USERLAND/components/openssl/openssl-default/build/sparcv9-wanboot LD_DBG=$ON/usr/src/psm/stand/boot/sparcv9/sun4/ld.dbg for i in `find $BUILD/crypto $BUILD/ssl -name '*.o'` @@ -241,111 +224,18 @@ and they are copied to both FIPS and non-FIPS 'patches' dir as soon as the Makefile is parsed. The Common patch filename has prefix '0', ----- - -008-6193522.patch -Give CA.pl better defaults. See 6193522 for more information. - -011-6546806.patch -Make sure the HMAC_CTX_init(3) man page gets delivered. See 6546806 for -more information. - -015-pkcs11_engine-0.9.8a.patch -Patch which adds the pkcs11 engine. See also the engine/pkcs11 -sub-directory. - -018-compiler_opts.patch -Adds five Solaris specific configurations (both 32bit and 64bit for both sparc -and x86, plus 64bit sparc for wanboot) to Configure which are then explicitly -used by the Makefiles. Wanboot configuration is special in that it doesn't link -with libc and uses -xF=%all to put functions in separate sections, so that -unused code can be discarded. - -Care should be taken if modifying this patch as changes to compile-time options -can change the ABI. One example of this is the use of RC4_INT vs RC4_CHAR. - -020-remove_rpath.patch -Prevent build binaries having an unnecessary runpath (/lib). - -023-noexstack.patch -Build with non-executable stacks and non-executable data (x86). - -027-6978791.patch -Modifies Makefile.shared so that libssl is built with -znodelete. - -028-enginesdir.patch -Adds a new "enginesdir" option to the Configure script which allows a user to -specify the engines directory. - -029-fork_safe.patch -Adds the code to setup internal mutexes and callback function. -See PSARC/2014/077. - -032-aes_cbc_len_check.patch -AES-CBC input length is checked to avoid segmentation fault. - -033-cert_chain.patch -Fixes the certificate chain bug. - -036-evp_leak.patch -Fixes the memory leak bug. - -038_remove_illegal_instruction_calls.patch -SPARC patch. Solaris-only patch. -For instructions in sparcv9cap.c, remove if not supported on any platforms. -Otherwise modify them to call getisax() to check for HW capability instead. - -039-internal_tests.patch -Remove test 'test_ca' because it depends on directories not present in the -build directory. - ========================= Non-FIPS specific Patches ========================= Non-FIPS specific patch files are located in the -components/openssl/openssl-1.0.1/patches dir. +components/openssl/openssl-default/patches dir. The Non-FIPS specific patch filename has prefix '1', ----- -101-manpage_openssl.patch -Force openssl to install man pages into man[1357]openssl instead of man[1357]. - -102-wanboot.patch: -Wanboot specific patches. -- modified Makefiles not to build in engines apps test tools -- not using vfprintf for error print in crypto/cryptlib.c -- not using ERR_load_DSO_strings() in crypto/err/err_all.c -- not using EVP_read_pw_string() in crypto/evp/evp_key.c - - reading password is implemented in disabled DES library -- avoid select() in crypto/rand/rand_unix.c -- direct reading of IP to avoid sscanf() in crypto/x509v3/v3_utl.c -- using functions from libsock in e_os.h -- by-passing version of sparc detection in crypto/sparcv9cap.c - - results in not using FPU for big numbers multiplication - - should be ok - original detection seems broken, FPU gets never used -- implementation of atoi() -- avoid using ssl_fill_hello_random() in s3_clnt.c - -103-openssl_t4_inline.patch -Add patch to support inline T4 instruction in OpenSSL upstream code until -OpenSSL 1.0.2 is released. - -104-suppress_v8plus_abi_warnings.patch -Suppress warnings about sparcv8+ ABI violation when building T4-specific -modules as 32-bit. - ========================= FIPS specific Patches ========================= FIPS specific patch files are located in the -components/openssl/openssl-1.0.1-fips-140/patches dir. +components/openssl/openssl-fips-140/patches dir. The FIPS specific patch filename has prefix '2', - ---- -201-openssl_fips.patch -Change openssl(1) to call the FIPS routines only if the fips mediator is activated. - -202-17952966.patch -FIPS version needs to build with '-lc' explicitly with stuido 12.3 and above. diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/common/patches/011-6546806.patch --- a/components/openssl/common/patches/011-6546806.patch Fri Aug 28 07:46:44 2015 -0700 +++ /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 -@@ -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 diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/common/patches/015-pkcs11_engine-0.9.8a.patch --- a/components/openssl/common/patches/015-pkcs11_engine-0.9.8a.patch Fri Aug 28 07:46:44 2015 -0700 +++ b/components/openssl/common/patches/015-pkcs11_engine-0.9.8a.patch Fri Aug 28 11:04:52 2015 -0700 @@ -23,7 +23,7 @@ # --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". -@@ -657,6 +661,9 @@ +@@ -716,6 +719,9 @@ my $idx_arflags = $idx++; my $idx_multilib = $idx++; @@ -33,18 +33,18 @@ my $prefix=""; my $libdir=""; my $openssldir=""; -@@ -882,6 +888,10 @@ - $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei; - $flags.=$_." "; - } +@@ -938,6 +944,10 @@ + { + $prefix=$1; + } + elsif (/^--pk11-libname=(.*)$/) + { + $pk11_libname=$1; + } - elsif (/^--prefix=(.*)$/) - { - $prefix=$1; -@@ -1049,6 +1059,13 @@ + elsif (/^--libdir=(.*)$/) + { + $libdir=$1; +@@ -1105,6 +11115,13 @@ exit 0; } @@ -58,7 +58,7 @@ if ($target =~ m/^CygWin32(-.*)$/) { $target = "Cygwin".$1; } -@@ -1215,6 +1232,8 @@ +@@ -1279,6 +1296,8 @@ if ($flags ne "") { $cflags="$flags$cflags"; } else { $no_user_cflags=1; } @@ -67,7 +67,7 @@ # Kerberos settings. The flavor must be provided from outside, either through # the script "config" or manually. if (!$no_krb5) -@@ -1604,6 +1623,7 @@ +@@ -1687,6 +1706,7 @@ s/^VERSION=.*/VERSION=$version/; s/^MAJOR=.*/MAJOR=$major/; s/^MINOR=.*/MINOR=$minor/; @@ -191,6 +191,6 @@ # endif void ENGINE_load_cryptodev(void); +void ENGINE_load_pk11(void); - void ENGINE_load_rsax(void); void ENGINE_load_rdrand(void); void ENGINE_load_builtin_engines(void); + diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/common/patches/018-compiler_opts.patch --- a/components/openssl/common/patches/018-compiler_opts.patch Fri Aug 28 07:46:44 2015 -0700 +++ b/components/openssl/common/patches/018-compiler_opts.patch Fri Aug 28 11:04:52 2015 -0700 @@ -4,15 +4,15 @@ # --- openssl-1.0.0d/Configure Thu Feb 10 20:02:41 2011 +++ /tmp/Configure Thu Feb 10 20:01:51 2011 -@@ -133,6 +133,7 @@ - my $x86_64_asm="x86_64cpuid.o:x86_64-gcc.o x86_64-mont.o x86_64-mont5.o x86_64-gf2m.o modexp512-x86_64.o::aes-x86_64.o vpaes-x86_64.o bsaes-x86_64.o aesni-x86_64.o aesni-sha1-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o::rc4-x86_64.o rc4-md5-x86_64.o:::wp-x86_64.o:cmll-x86_64.o cmll_misc.o:ghash-x86_64.o:"; - my $ia64_asm="ia64cpuid.o:bn-ia64.o ia64-mont.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o::rc4-ia64.o rc4_skey.o:::::ghash-ia64.o::void"; - my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o sparcv9a-mont.o:des_enc-sparc.o fcrypt_b.o:aes_core.o aes_cbc.o aes-sparcv9.o:::sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o:::::::ghash-sparcv9.o::void"; -+my $fips_sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o:des_enc-sparc.o fcrypt_b.o:aes_core.o aes_cbc.o aes-sparcv9.o:::sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o:::::::ghash-sparcv9.o::void"; - my $sparcv8_asm=":sparcv8.o:des_enc-sparc.o fcrypt_b.o:::::::::::::void"; - my $alpha_asm="alphacpuid.o:bn_asm.o alpha-mont.o:::::sha1-alpha.o:::::::ghash-alpha.o::void"; - my $mips32_asm=":bn-mips.o::aes_cbc.o aes-mips.o:::sha1-mips.o sha256-mips.o::::::::"; -@@ -257,6 +257,21 @@ +@@ -153,6 +153,7 @@ + my $x86_64_asm="x86_64cpuid.o:x86_64-gcc.o x86_64-mont.o x86_64-mont5.o x86_64-gf2m.o rsaz_exp.o rsaz-x86_64.o rsaz-avx2.o:ecp_nistz256.o ecp_nistz256-x86_64.o::aes-x86_64.o vpaes-x86_64.o bsaes-x86_64.o aesni-x86_64.o aesni-sha1-x86_64.o aesni-sha256-x86_64.o aesni-mb-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o sha1-mb-x86_64.o sha256-mb-x86_64.o::rc4-x86_64.o rc4-md5-x86_64.o:::wp-x86_64.o:cmll-x86_64.o cmll_misc.o:ghash-x86_64.o aesni-gcm-x86_64.o:"; + my $ia64_asm="ia64cpuid.o:bn-ia64.o ia64-mont.o:::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o::rc4-ia64.o rc4_skey.o:::::ghash-ia64.o::void"; + my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o sparcv9a-mont.o vis3-mont.o sparct4-mont.o sparcv9-gf2m.o::des_enc-sparc.o fcrypt_b.o dest4-sparcv9.o:aes_core.o aes_cbc.o aes-sparcv9.o aest4-sparcv9.o::md5-sparcv9.o:sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o::::::camellia.o cmll_misc.o cmll_cbc.o cmllt4-sparcv9.o:ghash-sparcv9.o::void"; ++my $fips_sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o vis3-mont.o sparct4-mont.o sparcv9-gf2m.o::des_enc-sparc.o fcrypt_b.o dest4-sparcv9.o:aes_core.o aes_cbc.o aes-sparcv9.o aest4-sparcv9.o::md5-sparcv9.o:sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o::::::camellia.o cmll_misc.o cmll_cbc.o cmllt4-sparcv9.o:ghash-sparcv9.o::void"; + my $sparcv8_asm=":sparcv8.o::des_enc-sparc.o fcrypt_b.o:::::::::::::void"; + my $alpha_asm="alphacpuid.o:bn_asm.o alpha-mont.o::::::sha1-alpha.o:::::::ghash-alpha.o::void"; + my $mips64_asm=":bn-mips.o mips-mont.o:::aes_cbc.o aes-mips.o:::sha1-mips.o sha256-mips.o sha512-mips.o::::::::"; +@@ -277,6 +278,21 @@ #"sunos-cc", "cc:-O4 -DNOPROTO -DNOCONST::(unknown):SUNOS::DES_UNROLL:${no_asm}::", "sunos-gcc","gcc:-O3 -mcpu=v8 -Dssize_t=int::(unknown):SUNOS::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL DES_PTR DES_RISC1:${no_asm}::", diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/common/patches/028-enginesdir.patch --- a/components/openssl/common/patches/028-enginesdir.patch Fri Aug 28 07:46:44 2015 -0700 +++ b/components/openssl/common/patches/028-enginesdir.patch Fri Aug 28 11:04:52 2015 -0700 @@ -13,7 +13,7 @@ # # --pk11-libname PKCS#11 library name. # (Default: none) -@@ -679,6 +679,7 @@ +@@ -741,6 +743,7 @@ my $prefix=""; my $libdir=""; my $openssldir=""; @@ -21,7 +21,7 @@ my $exe_ext=""; my $install_prefix= "$ENV{'INSTALL_PREFIX'}"; my $cross_compile_prefix=""; -@@ -917,6 +920,10 @@ +@@ -972,6 +975,10 @@ { $openssldir=$1; } @@ -32,7 +32,7 @@ elsif (/^--install.prefix=(.*)$/) { $install_prefix=$1; -@@ -1224,6 +1231,10 @@ +@@ -1285,6 +1292,10 @@ # we're ready to tolerate, so don't... $multilib="" if !-d "$prefix/lib$multilib"; @@ -43,7 +43,7 @@ $libdir="lib$multilib" if $libdir eq ""; $cflags = "$cflags$exp_cflags"; -@@ -1846,7 +1857,7 @@ +@@ -1934,7 +1945,7 @@ } elsif (/^#define\s+ENGINESDIR/) { diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/common/patches/029-fork_safe.patch --- a/components/openssl/common/patches/029-fork_safe.patch Fri Aug 28 07:46:44 2015 -0700 +++ b/components/openssl/common/patches/029-fork_safe.patch Fri Aug 28 11:04:52 2015 -0700 @@ -60,7 +60,7 @@ } void (*CRYPTO_get_locking_callback(void)) (int mode, int type, -@@ -402,6 +414,129@@ +@@ -402,6 +414,128@@ return (add_lock_callback); } @@ -78,7 +78,6 @@ + } +} + -+ +/* + * Implement Solaris's own dynamic locking routines. + */ @@ -217,7 +216,7 @@ return 1; } -@@ -531,7 +611,10 @@ +@@ -529,7 +669,10 @@ void CRYPTO_set_id_callback(unsigned long (*func) (void)) { @@ -242,8 +241,8 @@ #endif --- openssl-1.0.1f/crypto/sparccpuid.S.~1~ Fri Feb 7 10:41:37 2014 +++ openssl-1.0.1f/crypto/sparccpuid.S Thu Feb 6 16:04:14 2014 -@@ -398,5 +398,7 @@ - .size OPENSSL_cleanse,.-OPENSSL_cleanse +@@ -525,5 +525,7 @@ + .size _sparcv9_vis1_instrument_bus2,.-_sparcv9_vis1_instrument_bus2 .section ".init",#alloc,#execinstr + call solaris_locking_setup @@ -265,11 +264,14 @@ .hidden OPENSSL_ia32cap_P --- openssl-1.0.1f/crypto/x86cpuid.pl.~1~ Wed Feb 12 13:38:03 2014 +++ openssl-1.0.1f/crypto/x86cpuid.pl Wed Feb 12 13:38:31 2014 -@@ -353,6 +353,7 @@ +@@ -379,8 +379,10 @@ &ret (); - &function_end_B("OPENSSL_ia32_rdrand"); + &function_end_B("OPENSSL_ia32_rdseed"); +&initseg("solaris_locking_setup"); &initseg("OPENSSL_cpuid_setup"); - &asm_finish(); ++&hidden("solaris_locking_setup"); + &hidden("OPENSSL_cpuid_setup"); + &hidden("OPENSSL_ia32cap_P"); + diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/common/patches/032-aes_cbc_len_check.patch --- a/components/openssl/common/patches/032-aes_cbc_len_check.patch Fri Aug 28 07:46:44 2015 -0700 +++ b/components/openssl/common/patches/032-aes_cbc_len_check.patch Fri Aug 28 11:04:52 2015 -0700 @@ -3,7 +3,7 @@ # --- openssl-1.0.1e/crypto/evp/e_aes.c Tue Jul 2 11:03:12 2013 +++ openssl-1.0.1e/crypto/evp/e_aes.c.new Tue Jul 2 11:04:56 2013 -@@ -536,8 +536,12 @@ +@@ -1016,8 +1016,12 @@ static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/common/patches/033-cert_chain.patch --- a/components/openssl/common/patches/033-cert_chain.patch Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,210 +0,0 @@ -This patch comes from OpenSSL upstream code, and the change has been commited to OpenSSL 1.0.2. - http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=fbd2164044f92383955a801ad1b2857d71e83f27 - http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=51e7a4378a78bb0870a2cdc5c524c230c929ebcb - http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=2dabd822366df7b2608b55d5ca5f31d5d484cbaf - -Index: openssl/crypto/x509/x509_trs.c -============================================================================ -$ diff -ru crypto/x509/x509_trs.c crypto/x509/x509_trs.c ---- openssl/crypto/x509/x509_trs.c.orig 4 Dec 2012 17:26:04 -0000 1.133.2.11.2.6.2.3 -+++ openssl/crypto/x509/x509_trs.c 14 Dec 2012 14:30:45 -0000 1.133.2.11.2.6.2.4 -@@ -119,6 +119,14 @@ int X509_check_trust(X509 *x, int id, int flags) - int idx; - if (id == -1) - return 1; -+ /* We get this as a default value */ -+ if (id == 0) { -+ int rv; -+ rv = obj_trust(NID_anyExtendedKeyUsage, x, 0); -+ if (rv != X509_TRUST_UNTRUSTED) -+ return rv; -+ return trust_compat(NULL, x, 0); -+ } - idx = X509_TRUST_get_by_id(id); - if (idx == -1) - return default_trust(id, x, flags); -Index: openssl/crypto/x509/x509_vfy.c -============================================================================ -$ cvs diff -u -r1.105.2.9.2.4.2.3 -r1.105.2.9.2.4.2.4 x509_vfy.c ---- openssl/crypto/x509/x509_vfy.c 14 Dec 2012 12:53:48 -0000 1.105.2.9.2.4.2.3 -+++ openssl/crypto/x509/x509_vfy.c 14 Dec 2012 14:30:46 -0000 1.105.2.9.2.4.2.4 -@@ -149,6 +149,33 @@ - } - #endif - -+/* Given a certificate try and find an exact match in the store */ -+ -+static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) -+ { -+ STACK_OF(X509) *certs; -+ X509 *xtmp = NULL; -+ int i; -+ /* Lookup all certs with matching subject name */ -+ certs = ctx->lookup_certs(ctx, X509_get_subject_name(x)); -+ if (certs == NULL) -+ return NULL; -+ /* Look for exact match */ -+ for (i = 0; i < sk_X509_num(certs); i++) -+ { -+ xtmp = sk_X509_value(certs, i); -+ if (!X509_cmp(xtmp, x)) -+ break; -+ } -+ if (i < sk_X509_num(certs)) -+ CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509); -+ else -+ xtmp = NULL; -+ sk_X509_pop_free(certs, X509_free); -+ return xtmp; -+ } -+ -+ - int X509_verify_cert(X509_STORE_CTX *ctx) - { - X509 *x, *xtmp, *xtmp2, *chain_ss = NULL; -@@ -304,8 +331,17 @@ int X509_verify_cert(X509_STORE_CTX *ctx) - } - } while (retry); - -- /* Is last certificate looked up self signed? */ -- if (!ctx->check_issued(ctx, x, x)) { -+ i = check_trust(ctx); -+ -+ /* If explicitly rejected error */ -+ if (i == X509_TRUST_REJECTED) -+ goto end; -+ /* -+ * If not explicitly trusted then indicate error unless it's a single -+ * self signed certificate in which case we've indicated an error already -+ * and set bad_chain == 1 -+ */ -+ if (i != X509_TRUST_TRUSTED && !bad_chain) { - if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) { - if (ctx->last_untrusted >= num) - ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; -@@ -340,14 +376,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx) - ok = check_name_constraints(ctx); - - if (!ok) -- goto end; -- -- /* The chain extensions are OK: check trust */ -- -- if (param->trust > 0) -- ok = check_trust(ctx); -- -- if (!ok) - goto end; - - /* We may as well copy down any DSA parameters that are required */ -@@ -630,28 +658,53 @@ static int check_name_constraints(X509_STORE_CTX *ctx) - - static int check_trust(X509_STORE_CTX *ctx) - { --#ifdef OPENSSL_NO_CHAIN_VERIFY -- return 1; --#else - int i, ok; -- X509 *x; -+ X509 *x = NULL; - int (*cb) (int xok, X509_STORE_CTX *xctx); - cb = ctx->verify_cb; --/* For now just check the last certificate in the chain */ -- i = sk_X509_num(ctx->chain) - 1; -- x = sk_X509_value(ctx->chain, i); -- ok = X509_check_trust(x, ctx->param->trust, 0); -- if (ok == X509_TRUST_TRUSTED) -- return 1; -- ctx->error_depth = i; -- ctx->current_cert = x; -- if (ok == X509_TRUST_REJECTED) -- ctx->error = X509_V_ERR_CERT_REJECTED; -- else -- ctx->error = X509_V_ERR_CERT_UNTRUSTED; -- ok = cb(0, ctx); -- return ok; --#endif -+ /* Check all trusted certificates in chain */ -+ for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) { -+ x = sk_X509_value(ctx->chain, i); -+ ok = X509_check_trust(x, ctx->param->trust, 0); -+ /* If explicitly trusted return trusted */ -+ if (ok == X509_TRUST_TRUSTED) -+ return X509_TRUST_TRUSTED; -+ /* -+ * If explicitly rejected notify callback and reject if not -+ * overridden. -+ */ -+ if (ok == X509_TRUST_REJECTED) { -+ ctx->error_depth = i; -+ ctx->current_cert = x; -+ ctx->error = X509_V_ERR_CERT_REJECTED; -+ ok = cb(0, ctx); -+ if (!ok) -+ return X509_TRUST_REJECTED; -+ } -+ } -+ /* -+ * If we accept partial chains and have at least one trusted certificate -+ * return success. -+ */ -+ if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { -+ X509 *mx; -+ if (ctx->last_untrusted < sk_X509_num(ctx->chain)) -+ return X509_TRUST_TRUSTED; -+ x = sk_X509_value(ctx->chain, 0); -+ mx = lookup_cert_match(ctx, x); -+ if (mx) { -+ (void)sk_X509_set(ctx->chain, 0, mx); -+ X509_free(x); -+ ctx->last_untrusted = 0; -+ return X509_TRUST_TRUSTED; -+ } -+ } -+ -+ /* -+ * If no trusted certs in chain at all return untrusted and allow -+ * standard (no issuer cert) etc errors to be indicated. -+ */ -+ return X509_TRUST_UNTRUSTED; - } - - static int check_revocation(X509_STORE_CTX *ctx) -@@ -1526,6 +1579,8 @@ static int internal_verify(X509_STORE_CTX *ctx) - if (ctx->check_issued(ctx, xi, xi)) - xs = xi; - else { -+ if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN && n == 0) -+ return check_cert_time(ctx, xi); - if (n <= 0) { - ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; - ctx->current_cert = xi; -Index: openssl/crypto/x509/x509_vfy.h -============================================================================ -$ cvs diff -u -r1.67.2.3.4.1 -r1.67.2.3.4.2 x509_vfy.h ---- openssl/crypto/x509/x509_vfy.h 26 Sep 2012 13:50:42 -0000 1.67.2.3.4.1 -+++ openssl/crypto/x509/x509_vfy.h 14 Dec 2012 14:30:46 -0000 1.67.2.3.4.2 -@@ -412,6 +412,9 @@ - */ - # define X509_V_FLAG_NO_ALT_CHAINS 0x100000 - -+/* Allow partial chains if at least one certificate is in trusted store */ -+# define X509_V_FLAG_PARTIAL_CHAIN 0x80000 -+ - # define X509_VP_FLAG_DEFAULT 0x1 - # define X509_VP_FLAG_OVERWRITE 0x2 - # define X509_VP_FLAG_RESET_FLAGS 0x4 -Index: openssl/apps/apps.c -============================================================================ -$ cvs diff -u -r1.133.2.11.2.6.2.3 -r1.133.2.11.2.6.2.4 apps.c ---- openssl/apps/apps.c 4 Dec 2012 17:26:04 -0000 1.133.2.11.2.6.2.3 -+++ openssl/apps/apps.c 14 Dec 2012 14:30:45 -0000 1.133.2.11.2.6.2.4 -@@ -2238,6 +2238,8 @@ - flags |= X509_V_FLAG_NOTIFY_POLICY; - else if (!strcmp(arg, "-check_ss_sig")) - flags |= X509_V_FLAG_CHECK_SS_SIGNATURE; -+ else if (!strcmp(arg, "-partial_chain")) -+ flags |= X509_V_FLAG_PARTIAL_CHAIN; - else if (!strcmp(arg, "-no_alt_chains")) - flags |= X509_V_FLAG_NO_ALT_CHAINS; - else diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/common/patches/036-evp_leak.patch --- a/components/openssl/common/patches/036-evp_leak.patch Fri Aug 28 07:46:44 2015 -0700 +++ b/components/openssl/common/patches/036-evp_leak.patch Fri Aug 28 11:04:52 2015 -0700 @@ -2,7 +2,7 @@ --- openssl-1.0.1f/crypto/evp/evp_enc.c.orig Mon Feb 11 07:26:04 2013 +++ openssl-1.0.1f/crypto/evp/evp_enc.c Mon Feb 3 16:40:48 2014 -@@ -379,11 +379,13 @@ +@@ -392,11 +392,13 @@ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { ret = M_do_cipher(ctx, out, NULL, 0); @@ -20,7 +20,7 @@ } b = ctx->cipher->block_size; -@@ -390,7 +392,8 @@ +@@ -403,7 +405,8 @@ OPENSSL_assert(b <= sizeof ctx->buf); if (b == 1) { *outl = 0; @@ -30,7 +30,7 @@ } bl = ctx->buf_len; if (ctx->flags & EVP_CIPH_NO_PADDING) { -@@ -397,10 +400,12 @@ +@@ -410,10 +413,12 @@ if (bl) { EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); @@ -45,7 +45,7 @@ } n = b - bl; -@@ -411,6 +416,11 @@ +@@ -424,6 +429,11 @@ if (ret) *outl = b; @@ -57,7 +57,7 @@ return ret; } -@@ -478,6 +488,7 @@ +@@ -491,6 +501,7 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) { int i, n; @@ -65,7 +65,7 @@ unsigned int b; *outl = 0; -@@ -483,11 +494,13 @@ +@@ -496,11 +507,13 @@ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { i = M_do_cipher(ctx, out, NULL, 0); @@ -83,7 +83,7 @@ } b = ctx->cipher->block_size; -@@ -495,10 +508,12 @@ +@@ -508,10 +521,12 @@ if (ctx->buf_len) { EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); @@ -98,7 +98,7 @@ } if (b > 1) { if (ctx->buf_len || !ctx->final_used) { -@@ -503,7 +518,8 @@ +@@ -516,7 +531,8 @@ if (b > 1) { if (ctx->buf_len || !ctx->final_used) { EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH); @@ -108,7 +108,7 @@ } OPENSSL_assert(b <= sizeof ctx->final); -@@ -514,7 +530,8 @@ +@@ -527,7 +543,8 @@ n = ctx->final[b - 1]; if (n == 0 || n > (int)b) { EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT); @@ -118,7 +118,7 @@ } for (i = 0; i < n; i++) { if (ctx->final[--b] != n) { -@@ -519,7 +536,8 @@ +@@ -532,7 +549,8 @@ for (i = 0; i < n; i++) { if (ctx->final[--b] != n) { EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT); @@ -128,7 +128,7 @@ } } n = ctx->cipher->block_size - n; -@@ -528,7 +546,12 @@ +@@ -541,7 +559,12 @@ *outl = n; } else *outl = 0; diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/common/patches/038-remove_illegal_instruction_calls.patch --- a/components/openssl/common/patches/038-remove_illegal_instruction_calls.patch Fri Aug 28 07:46:44 2015 -0700 +++ b/components/openssl/common/patches/038-remove_illegal_instruction_calls.patch Fri Aug 28 11:04:52 2015 -0700 @@ -4,26 +4,19 @@ # --- openssl-1.0.1g/crypto/sparcv9cap.c.~1~ Thu May 1 13:07:00 2014 +++ openssl-1.0.1g/crypto/sparcv9cap.c Thu May 1 13:11:33 2014 -@@ -2,9 +2,9 @@ +@@ -2,10 +2,10 @@ #include #include #include -#include #include + #include #include +#include - #define SPARCV9_TICK_PRIVILEGED (1<<0) - #define SPARCV9_PREFER_FPU (1<<1) -@@ -11,6 +11,7 @@ - #define SPARCV9_VIS1 (1<<2) - #define SPARCV9_VIS2 (1<<3) /* reserved */ - #define SPARCV9_FMADD (1<<4) /* reserved for SPARC64 V */ -+#define SPARCV9_BLK (1<<5) + #include "sparc_arch.h" - static int OPENSSL_sparcv9cap_P = SPARCV9_TICK_PRIVILEGED; - -@@ -31,10 +31,7 @@ +@@ -69,13 +69,8 @@ } unsigned long _sparcv9_rdtick(void); @@ -31,10 +24,13 @@ unsigned long _sparcv9_vis1_instrument(void); -void _sparcv9_vis2_probe(void); -void _sparcv9_fmadd_probe(void); + unsigned long _sparcv9_rdcfr(void); +-void _sparcv9_vis3_probe(void); +-unsigned long _sparcv9_random(void); + size_t _sparcv9_vis1_instrument_bus(unsigned int *, size_t); + size_t _sparcv9_vis1_instrument_bus2(unsigned int *, size_t, size_t); - unsigned long OPENSSL_rdtsc(void) - { -@@ -170,18 +167,11 @@ +@@ -231,18 +227,11 @@ #else @@ -54,15 +50,15 @@ if (trigger) return; -@@ -192,54 +182,24 @@ +@@ -255,47 +255,23 @@ return; } + (void) getisax(&ui, 1); + /* Initial value, fits UltraSPARC-I&II... */ -- OPENSSL_sparcv9cap_P = SPARCV9_PREFER_FPU | SPARCV9_TICK_PRIVILEGED; -+ OPENSSL_sparcv9cap_P = SPARCV9_BLK; +- OPENSSL_sparcv9cap_P[0] = SPARCV9_PREFER_FPU | SPARCV9_TICK_PRIVILEGED; ++ OPENSSL_sparcv9cap_P[0] = SPARCV9_BLK; - sigfillset(&all_masked); - sigdelset(&all_masked, SIGILL); @@ -85,42 +81,83 @@ - - if (sigsetjmp(common_jmp, 1) == 0) { - _sparcv9_rdtick(); -- OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED; +- OPENSSL_sparcv9cap_P[0] &= ~SPARCV9_TICK_PRIVILEGED; - } - - if (sigsetjmp(common_jmp, 1) == 0) { - _sparcv9_vis1_probe(); -- OPENSSL_sparcv9cap_P |= SPARCV9_VIS1; +- OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS1 | SPARCV9_BLK; - /* detect UltraSPARC-Tx, see sparccpud.S for details... */ - if (_sparcv9_vis1_instrument() >= 12) -- OPENSSL_sparcv9cap_P &= ~(SPARCV9_VIS1 | SPARCV9_PREFER_FPU); +- OPENSSL_sparcv9cap_P[0] &= ~(SPARCV9_VIS1 | SPARCV9_PREFER_FPU); - else { - _sparcv9_vis2_probe(); -- OPENSSL_sparcv9cap_P |= SPARCV9_VIS2; +- OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS2; + if (ui & AV_SPARC_VIS) { + /* detect UltraSPARC-Tx, see sparccpuid.S for details... */ + if (_sparcv9_vis1_instrument() < 7) -+ OPENSSL_sparcv9cap_P |= SPARCV9_TICK_PRIVILEGED; ++ OPENSSL_sparcv9cap_P[0] |= SPARCV9_TICK_PRIVILEGED; + if (_sparcv9_vis1_instrument() < 12) { -+ OPENSSL_sparcv9cap_P |= SPARCV9_VIS1|SPARCV9_PREFER_FPU; ++ OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS1|SPARCV9_PREFER_FPU; + if (ui & AV_SPARC_VIS2) -+ OPENSSL_sparcv9cap_P |= SPARCV9_VIS2; ++ OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS2; } } - if (sigsetjmp(common_jmp, 1) == 0) { - _sparcv9_fmadd_probe(); -+ if (ui & AV_SPARC_FMAF) - OPENSSL_sparcv9cap_P |= SPARCV9_FMADD; ++ if (ui & AV_SPARC_FMAF) { + OPENSSL_sparcv9cap_P[0] |= SPARCV9_FMADD; + } + +@@ -303,36 +279,23 @@ + * VIS3 flag is tested independently from VIS1, unlike VIS2 that is, + * because VIS3 defines even integer instructions. + */ +- if (sigsetjmp(common_jmp, 1) == 0) { +- _sparcv9_vis3_probe(); +- OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS3; ++ if (ui & AV_SPARC_VIS3) { ++ OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS3; + } +-# if 0 /* was planned at some point but never +- * implemented in hardware */ +- if (sigsetjmp(common_jmp, 1) == 0) { +- (void)_sparcv9_random(); +- OPENSSL_sparcv9cap_P[0] |= SPARCV9_RANDOM; - } -- +-# endif + +- /* +- * In wait for better solution _sparcv9_rdcfr is masked by +- * VIS3 flag, because it goes to uninterruptable endless +- * loop on UltraSPARC II running Solaris. Things might be +- * different on Linux... +- */ +- if ((OPENSSL_sparcv9cap_P[0] & SPARCV9_VIS3) && +- sigsetjmp(common_jmp, 1) == 0) { ++#define AV_T4_MECHS (AV_SPARC_AES | AV_SPARC_DES | AV_SPARC_KASUMI | \ ++ AV_SPARC_CAMELLIA | AV_SPARC_MD5 | AV_SPARC_SHA1 | \ ++ AV_SPARC_SHA256 | AV_SPARC_SHA512 | AV_SPARC_MPMUL | \ ++ AV_SPARC_CRC32C) ++ ++ if ((OPENSSL_sparcv9cap_P[0]&SPARCV9_VIS3) && (ui & AV_T4_MECHS)) { + OPENSSL_sparcv9cap_P[1] = (unsigned int)_sparcv9_rdcfr(); + } + - sigaction(SIGBUS, &bus_oact, NULL); - sigaction(SIGILL, &ill_oact, NULL); -- ++ if (sizeof(size_t) == 8) { ++ OPENSSL_sparcv9cap_P[0] |= SPARCV9_64BIT_STACK; ++ } + - sigprocmask(SIG_SETMASK, &oset, NULL); - } - - #endif +- +- if (sizeof(size_t) == 8) +- OPENSSL_sparcv9cap_P[0] |= SPARCV9_64BIT_STACK; + # ifdef __linux + else { + int ret = syscall(340); --- openssl-1.0.1g/crypto/sparccpuid.S.~1~ Thu May 1 13:07:00 2014 +++ openssl-1.0.1g/crypto/sparccpuid.S Thu May 1 13:11:33 2014 @@ -232,16 +232,6 @@ @@ -140,7 +177,7 @@ ! Probe and instrument VIS1 instruction. Output is number of cycles it ! takes to execute rdtick and pair of VIS1 instructions. US-Tx VIS unit ! is slow (documented to be 6 cycles on T2) and the core is in-order -@@ -296,24 +286,6 @@ +@@ -303,24 +293,6 @@ .type _sparcv9_vis1_instrument,#function .size _sparcv9_vis1_instrument,.-_sparcv9_vis1_instrument @@ -162,6 +199,6 @@ -.type _sparcv9_fmadd_probe,#function -.size _sparcv9_fmadd_probe,.-_sparcv9_fmadd_probe - - .global OPENSSL_cleanse - .align 32 - OPENSSL_cleanse: + .global _sparcv9_rdcfr + .align 8 + _sparcv9_rdcfr: diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/common/patches/039-internal_tests.patch --- a/components/openssl/common/patches/039-internal_tests.patch Fri Aug 28 07:46:44 2015 -0700 +++ b/components/openssl/common/patches/039-internal_tests.patch Fri Aug 28 11:04:52 2015 -0700 @@ -6,12 +6,12 @@ # --- a/test/Makefile.orig Thu Apr 2 12:11:12 2015 +++ b/test/Makefile Thu Apr 2 12:11:21 2015 -@@ -142,7 +142,7 @@ +@@ -146,7 +146,7 @@ test_rand test_bn test_ec test_ecdsa test_ecdh \ test_enc test_x509 test_rsa test_crl test_sid \ test_gen test_req test_pkcs7 test_verify test_dh test_dsa \ - test_ss test_ca test_engine test_evp test_evp_extra test_ssl test_tsa test_ige \ + test_ss test_engine test_evp test_evp_extra test_ssl test_tsa test_ige \ - test_jpake test_srp test_cms test_heartbeat test_constant_time test_verify_extra + test_jpake test_srp test_cms test_ocsp test_v3name test_heartbeat \ + test_constant_time test_verify_extra - test_evp: diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/common/patches/040-uninitialized_ctx.patch --- a/components/openssl/common/patches/040-uninitialized_ctx.patch Fri Aug 28 07:46:44 2015 -0700 +++ b/components/openssl/common/patches/040-uninitialized_ctx.patch Fri Aug 28 11:04:52 2015 -0700 @@ -4,7 +4,7 @@ diff -ru openssl-1.0.1m/crypto/evp/evp_enc.c openssl-1.0.1m/crypto/evp/evp_enc.c.new --- openssl-1.0.1m/crypto/evp/evp_enc.c Thu May 7 09:46:32 2015 +++ openssl-1.0.1m/crypto/evp/evp_enc.c.new Thu May 7 09:46:23 2015 -@@ -179,6 +179,7 @@ +@@ -185,6 +185,7 @@ EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE); return 0; } diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/common/patches/041_rm_sslv2_v3.patch --- a/components/openssl/common/patches/041_rm_sslv2_v3.patch Fri Aug 28 07:46:44 2015 -0700 +++ b/components/openssl/common/patches/041_rm_sslv2_v3.patch Fri Aug 28 11:04:52 2015 -0700 @@ -35,7 +35,7 @@ # endif --- openssl-1.0.1/ssl/s2_srvr.c Fri May 8 09:38:02 2015 +++ openssl-1.0.1/ssl/s2_srvr.c.new Fri May 8 09:53:43 2015 -@@ -1150,6 +1150,13 @@ +@@ -1148,6 +1148,13 @@ } #else /* !OPENSSL_NO_SSL2 */ @@ -51,7 +51,7 @@ # endif --- openssl-1.0.1/ssl/ssl.h Tue May 26 11:13:15 2015 +++ openssl-1.0.1/ssl/ssl.h.new Tue May 26 11:32:09 2015 -@@ -2017,12 +2017,26 @@ +@@ -2345,12 +2345,26 @@ /* This sets the 'default' SSL version that SSL_new() will create */ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); @@ -441,7 +441,7 @@ there are no ciphersuites specific to TLS v1.1. =item B, B, B -@@ -569,16 +555,6 @@ +@@ -579,16 +565,6 @@ TLS_PSK_WITH_AES_128_CBC_SHA PSK-AES128-CBC-SHA TLS_PSK_WITH_AES_256_CBC_SHA PSK-AES256-CBC-SHA @@ -457,31 +457,28 @@ - =head1 NOTES - The non-ephemeral DH modes are currently unimplemented in OpenSSL + Some compiled versions of OpenSSL may not include all the ciphers --- openssl-1.0.1/doc/apps/s_client.pod Thu Mar 19 06:37:10 2015 +++ openssl-1.0.1/doc/apps/s_client.pod.new Tue May 26 12:15:40 2015 -@@ -31,12 +31,12 @@ +@@ -32,11 +32,9 @@ [B<-ign_eof>] [B<-no_ign_eof>] [B<-quiet>] -[B<-ssl2>] -[B<-ssl3>] [B<-tls1>] --[B<-no_ssl2>] --[B<-no_ssl3>] +[B<-tls1_1>] +[B<-tls1_2>] +-[B<-no_ssl2>] +-[B<-no_ssl3>] [B<-no_tls1>] -+[B<-no_tls1_1>] -+[B<-no_tls1_2>] - [B<-bugs>] - [B<-cipher cipherlist>] - [B<-serverpref>] -@@ -196,11 +196,11 @@ + [B<-no_tls1_1>] + [B<-no_tls1_2>] +@@ -201,11 +199,11 @@ given as a hexadecimal number without leading 0x, for example -psk 1a2b3c4d. --=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1> +-=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> +=item B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> -these options disable the use of certain SSL or TLS protocols. By default @@ -490,9 +487,9 @@ -servers and permit them to use SSL v3, SSL v2 or TLS as appropriate. +servers. - Unfortunately there are a lot of ancient and broken servers in use which + Unfortunately there are still ancient and broken servers in use which cannot handle this technique and will fail to connect. Some servers only -@@ -219,10 +219,6 @@ +@@ -227,10 +225,6 @@ supported cipher in the list sent by the client. See the B command for more information. @@ -503,7 +500,7 @@ =item B<-starttls protocol> send the protocol-specific message(s) to switch to TLS for communication. -@@ -299,8 +295,8 @@ +@@ -314,8 +308,8 @@ then an HTTP command can be given such as "GET /" to retrieve a web page. If the handshake fails then there are several possible causes, if it is @@ -514,7 +511,7 @@ in case it is a buggy server. In particular you should play with these options B submitting a bug report to an OpenSSL mailing list. -@@ -322,10 +318,6 @@ +@@ -337,10 +331,6 @@ If there are problems verifying a server certificate then the B<-showcerts> option can be used to show the whole chain. @@ -525,9 +522,9 @@ The B utility is a test tool and is designed to continue the handshake after any certificate verification errors. As a result it will accept any certificate chain (trusted or not) sent by the peer. None test ---- openssl-1.0.1/doc/apps/s_server.pod Thu Mar 19 06:37:10 2015 -+++ openssl-1.0.1/doc/apps/s_server.pod.new Tue May 26 12:15:02 2015 -@@ -38,12 +38,12 @@ +--- openssl-1.0.1/doc/apps/s_server.pod Thu Mar 19 06:37:10 2015 ++++ openssl-1.0.1/doc/apps/s_server.pod.new Tue May 26 12:15:02 2015 +@@ -39,12 +39,12 @@ [B<-serverpref>] [B<-quiet>] [B<-no_tmp_rsa>] @@ -542,9 +539,9 @@ +[B<-no_tls1_1>] +[B<-no_tls1_2>] [B<-no_dhe>] - [B<-no_ecdhe>] [B<-bugs>] -@@ -216,11 +216,11 @@ + [B<-hack>] +@@ -217,11 +217,11 @@ given as a hexadecimal number without leading 0x, for example -psk 1a2b3c4d. diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/common/patches/042-suppress_v8plus_abi_warnings.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/openssl/common/patches/042-suppress_v8plus_abi_warnings.patch Fri Aug 28 11:04:52 2015 -0700 @@ -0,0 +1,70 @@ +# +# Patch developed in-house. Solaris-specific; not suitable for upstream. +# +# Suppress warnings about sparcv8+ ABI violation +# when building T4-specific modules as 32-bit: +# v8+ ABI violation: illegal use of %i or %l register as rs1 in "brnz,a" instruction +# This has been confirmed as a valid usecase and is thus intentional. +# +--- a/crypto/aes/Makefile.orig čt dub 30 03:15:03 2015 ++++ b/crypto/aes/Makefile čt dub 30 03:19:32 2015 +@@ -75,6 +75,9 @@ + aest4-sparcv9.s: asm/aest4-sparcv9.pl ../perlasm/sparcv9_modes.pl + $(PERL) asm/aest4-sparcv9.pl $(CFLAGS) > $@ + ++aest4-sparcv9.o: aest4-sparcv9.s ++ $(AS) $(ASFLAGS) -Wa,-n -o $@ $^ ++ + aes-ppc.s: asm/aes-ppc.pl + $(PERL) asm/aes-ppc.pl $(PERLASM_SCHEME) $@ + vpaes-ppc.s: asm/vpaes-ppc.pl +--- a/crypto/sha/Makefile.orig čt dub 30 14:37:32 2015 ++++ b/crypto/sha/Makefile čt dub 30 14:40:49 2015 +@@ -73,6 +73,8 @@ + sha1-sparcv9.S: asm/sha1-sparcv9.pl; $(PERL) asm/sha1-sparcv9.pl $@ $(CFLAGS) + sha256-sparcv9.S:asm/sha512-sparcv9.pl; $(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS) + sha512-sparcv9.S:asm/sha512-sparcv9.pl; $(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS) ++sha512-sparcv9.o: sha512-sparcv9.S ++ $(CC) $(CFLAGS) -Wa,-n -c -o $@ $^ + + sha1-ppc.s: asm/sha1-ppc.pl; $(PERL) asm/sha1-ppc.pl $(PERLASM_SCHEME) $@ + sha256-ppc.s: asm/sha512-ppc.pl; $(PERL) asm/sha512-ppc.pl $(PERLASM_SCHEME) $@ +--- a/crypto/bn/Makefile.orig čt dub 30 14:43:20 2015 ++++ b/crypto/bn/Makefile čt dub 30 14:45:11 2015 +@@ -79,8 +79,12 @@ + $(PERL) asm/sparcv9-mont.pl $(CFLAGS) > $@ + vis3-mont.s: asm/vis3-mont.pl + $(PERL) asm/vis3-mont.pl $(CFLAGS) > $@ ++vis3-mont.o: vis3-mont.s ++ $(AS) $(ASFLAGS) -Wa,-n -o $@ $^ + sparct4-mont.S: asm/sparct4-mont.pl + $(PERL) asm/sparct4-mont.pl $(CFLAGS) > $@ ++sparct4-mont.o: sparct4-mont.S ++ $(CC) $(CFLAGS) -Wa,-n -c -o $@ $^ + sparcv9-gf2m.S: asm/sparcv9-gf2m.pl + $(PERL) asm/sparcv9-gf2m.pl $(CFLAGS) > $@ + +--- a/crypto/camellia/Makefile.orig Fri Aug 21 14:51:49 2015rypto/camellia/Makef ++++ b/crypto/camellia/Makefile Fri Aug 21 14:53:18 2015.2d/crypto/camellia/Make +@@ -51,6 +51,9 @@ + cmllt4-sparcv9.s: asm/cmllt4-sparcv9.pl ../perlasm/sparcv9_modes.pl + $(PERL) asm/cmllt4-sparcv9.pl $(CFLAGS) > $@ + ++cmllt4-sparcv9.o: cmllt4-sparcv9.s ++ $(AS) $(ASFLAGS) -Wa,-n -o $@ $^ ++ + files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +--- a/crypto/modes/Makefile.orig Fri Aug 21 15:22:37 2015 ++++ b/crypto/modes/Makefile Fri Aug 21 15:26:12 2015 +@@ -54,6 +54,9 @@ + $(PERL) asm/aesni-gcm-x86_64.pl $(PERLASM_SCHEME) > $@ + ghash-sparcv9.s: asm/ghash-sparcv9.pl + $(PERL) asm/ghash-sparcv9.pl $@ $(CFLAGS) ++ghash-sparcv9.o: ghash-sparcv9.s ++ $(AS) $(ASFLAGS) -Wa,-n -o $@ $^ ++ + ghash-alpha.s: asm/ghash-alpha.pl + (preproc=$$$$.$@.S; trap "rm $$preproc" INT; \ + $(PERL) asm/ghash-alpha.pl > $$preproc && \ diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/common/patches/043-x86_wrong_platform.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/openssl/common/patches/043-x86_wrong_platform.patch Fri Aug 28 11:04:52 2015 -0700 @@ -0,0 +1,15 @@ +# +# This was developed in house to fix the wrong platform detection for Solaris. +# Reported to the upstream. +# +--- openssl-1.0.2d/crypto/perlasm/x86gas.pl Thu Jul 9 04:57:15 2015 ++++ openssl-1.0.2d/crypto/perlasm/x86gas.pl.new Thu Jul 30 15:17:14 2015 +@@ -196,8 +196,6 @@ + &::mov($dst,&::DWP("$indirect-$reflabel",$base)); + $non_lazy_ptr{"$nmdecor$sym"}=$indirect; + } +- elsif ($sym eq "OPENSSL_ia32cap_P" && $::elf>0) +- { &::lea($dst,&::DWP("$sym-$reflabel",$base)); } + else + { &::lea($dst,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]", + $base)); diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1-fips-140/Makefile --- a/components/openssl/openssl-1.0.1-fips-140/Makefile Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,211 +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, 2015, Oracle and/or its affiliates. All rights reserved. -# - -include ../../../make-rules/shared-macros.mk - -PATH=$(SPRO_VROOT)/bin:/usr/bin:/usr/gnu/bin:/usr/perl5/bin -ifeq ($(strip $(PARFAIT_BUILD)),yes) -PATH=$(PARFAIT_TOOLS):$(SPRO_VROOT)/bin:/usr/bin:/usr/gnu/bin:/usr/perl5/bin -endif - -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 = 1.0.1p -IPS_COMPONENT_VERSION = 2.0.6 -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:bd5ee6803165c0fb60bbecbacacf244f1f90d2aa0d71353af610c29121e9b2f1 -COMPONENT_ARCHIVE_URL = $(COMPONENT_PROJECT_URL)source/$(COMPONENT_ARCHIVE) -COMPONENT_BUGDB= library/openssl - -TPNO= 23452 - -# Clone the patch files to the patches-all dir. -# COPY_COMMON_FILES is there so that rsync is called as soon as -# the Makefile is parsed. -PATCH_DIR=patches-all -CLEAN_PATHS += $(PATCH_DIR) -COPY_COMMON_FILES:= $(shell rsync -ac ../common/patches/ patches/ $(PATCH_DIR)) - -# OpenSSL FIPS directory -OPENSSL_FIPS_DIR = $(COMPONENT_DIR)/../openssl-fips - -include $(WS_MAKE_RULES)/prep.mk -include $(WS_MAKE_RULES)/configure.mk -include $(WS_MAKE_RULES)/ips.mk -include $(WS_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-1.0.1-fips-140/openssl-fips/g' ) -FIPS_BUILD_DIR_64 = $(shell echo $(BUILD_DIR_64) | \ - sed -e 's/openssl-1.0.1-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-ec2m -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/" -CONFIGURE_OPTIONS += --with-fipsdir="$(BUILD_DIR_$(BITS))" - -# MD2 is not enabled by default in OpensSSL but some software we have in -# Userland needs it. One example is nmap. -CONFIGURE_OPTIONS += enable-md2 -CONFIGURE_OPTIONS += no-seed - -# Disable SSLv2 and SSLv3 protocols -CONFIGURE_OPTIONS += no-ssl2 -CONFIGURE_OPTIONS += no-ssl3 - -# 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-fips-sparcv9-cc-sunw -CONFIGURE_OPTIONS64_i386 = solaris64-x86_64-cc-sunw -CONFIGURE_OPTIONS64_sparc = solaris64-fips-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; ) - -# Enable ASLR for this component -ASLR_MODE = $(ASLR_ENABLE) - -# We must make sure that openssl-fips component is built before this 1.0.1 -# 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) $@) - -# 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. -# We also copy some FIPS specific header files needed to build FIPS version -# of OpenSSL from FIPS module. -COMPONENT_PRE_BUILD_ACTION = \ - ( $(LN) -fs $(COMPONENT_DIR)/engines/pkcs11/* $(@D)/engines; \ - $(MKDIR) $(@D)/bin; \ - $(LN) -fs $(OPENSSL_FIPS_DIR)/openssl-fips-ecp-$(IPS_COMPONENT_VERSION)/fips/fips.h $(@D)/include/openssl; \ - $(LN) -fs $(OPENSSL_FIPS_DIR)/openssl-fips-ecp-$(IPS_COMPONENT_VERSION)/fips/fipssyms.h $(@D)/include/openssl; \ - $(LN) -fs $(OPENSSL_FIPS_DIR)/openssl-fips-ecp-$(IPS_COMPONENT_VERSION)/fips/rand/fips_rand.h $(@D)/include/openssl; \ - $(LN) -fs $(OPENSSL_FIPS_DIR)/openssl-fips-ecp-$(IPS_COMPONENT_VERSION)/fips/fipsld $(@D)/bin/; \ - $(LN) -fs $(OPENSSL_FIPS_DIR)/build/$(MACH$(BITS))/fips/fips_standalone_sha1 $(@D)/bin/; \ - $(LN) -fs $(COMPONENT_DIR)/build/$(MACH$(BITS))/fips_premain_dso $(@D)/bin/;) - -# OpenSSL does not install into /$(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); ) - -$(SOURCE_DIR)/.prep: $(COMPONENT_DIR)/../openssl-fips/build/$(MACH32)/.installed \ - $(COMPONENT_DIR)/../openssl-fips/build/$(MACH64)/.installed - -configure: $(CONFIGURE_32_and_64) - -build: $(BUILD_32_and_64) - -# 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) - -# There are also separate STC test suites 'openssl' and 'openssl-engine' -# for regression testing. These internal tests are unit tests only. -COMPONENT_TEST_TARGETS = test -test: $(TEST_32_and_64) - -system-test: $(SYSTEM_TESTS_NOT_IMPLEMENTED) - - -REQUIRED_PACKAGES += developer/build/makedepend -REQUIRED_PACKAGES += system/library diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11.c --- a/components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11.c Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3667 +0,0 @@ -/* - * Copyright (c) 2004, 2015, 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 - * licensing@OpenSSL.org. - * - * 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 - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef OPENSSL_NO_RSA -#include -#endif -#ifndef OPENSSL_NO_DSA -#include -#endif -#ifndef OPENSSL_NO_DH -#include -#endif -#include -#include -#include -#include -#include -#include - -#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 - -#include -#include -#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" - -/* - * 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 = NULL; - -#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, - PK11_AES_128_CTR, - PK11_AES_192_CTR, - PK11_AES_256_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); -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, size_t 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_choose_rand_slot(CK_TOKEN_INFO token_info, - CK_SLOT_ID current_slot); -static void pk11_choose_pubkey_slot(CK_MECHANISM_INFO mech_info, - CK_TOKEN_INFO token_info, CK_SLOT_ID current_slot, CK_RV rv, - int best_number_of_mechs, CK_SLOT_ID best_pubkey_slot_sofar); -static void pk11_choose_cipher_digest(int *local_cipher_nids, - int *local_digest_nids, CK_FUNCTION_LIST_PTR pflist, - CK_SLOT_ID current_slot); -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, }, - { PK11_AES_128_CTR, NID_aes_128_ctr, 16, 16, 16, - CKK_AES, CKM_AES_CTR, }, - { PK11_AES_192_CTR, NID_aes_192_ctr, 16, 24, 24, - CKK_AES, CKM_AES_CTR, }, - { PK11_AES_256_CTR, NID_aes_256_ctr, 16, 32, 32, - CKK_AES, CKM_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 - }; - -static EVP_CIPHER pk11_aes_128_ctr = - { - NID_aes_128_ctr, - 16, 16, 16, - EVP_CIPH_CTR_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_aes_192_ctr, - 16, 24, 16, - EVP_CIPH_CTR_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_aes_256_ctr, - 16, 32, 16, - EVP_CIPH_CTR_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_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, - EVP_MD_FLAG_FIPS, - 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, - EVP_MD_FLAG_FIPS, - 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, - EVP_MD_FLAG_FIPS, - 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, - EVP_MD_FLAG_FIPS, - 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, - EVP_MD_FLAG_FIPS, - 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 ENGINE* pk11_engine = NULL; - -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; - } - } - /* Free uri_lock */ - (void) pthread_mutex_destroy(uri_lock); - OPENSSL_free(uri_lock); - uri_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); - - if (!ENGINE_set_pkey_meths(e, pk11_engine_pkey_methods)) - 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)); - } - -/* - * Helper function that unsets reference to current engine (pk11_engine = NULL). - * - * Use of local variable only seems clumsy, it needs to be this way! - * This is to prevent double free in the unlucky scenario: - * ENGINE_free calls pk11_destroy calls pk11_finish calls ENGINE_free - * Setting pk11_engine to NULL prior to ENGINE_free() avoids this. - */ -static void pk11_engine_free() - { - ENGINE* old_engine = pk11_engine; - - if (old_engine) - { - pk11_engine = NULL; - } - } - -/* - * 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; - - if (e != pk11_engine) - { - pk11_engine_free(); - pk11_engine = e; - } - - /* - * 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 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; - - /* Attempt to load PKCS#11 library. */ - if (!pk11_dso) - { - pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0); - if (pk11_dso == NULL) - { - PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE); - goto err; - } - } - -#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 (!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) - { - int rtn = 1; - - free_PK11_LIBNAME(); - ERR_unload_pk11_strings(); - if (pk11_library_initialized == CK_TRUE) - rtn = pk11_finish(e); - - return (rtn); - } - -/* - * Termination function to clean up the session, the token, and the pk11 - * library. - */ -/* ARGSUSED */ -static int pk11_finish(ENGINE *e) - { - int i; - - /* - * Make sure, right engine instance is being destroyed. - * Engine e may be the wrong instance if - * 1) either someone calls ENGINE_load_pk11 twice - * 2) or last ref. to an already finished engine is being destroyed - */ - if (e != pk11_engine) - goto err; - - 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); - - /* Global session is not present when there are no slots. */ - if (global_session != CK_INVALID_HANDLE) - { - 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 - 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; - pk11_engine_free(); - /* - * 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; - } - } - 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; - CK_AES_CTR_PARAMS ctr_params; - - /* - * 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); - - 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 - { - 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, size_t 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_aes_128_ctr: - *cipher = &pk11_aes_128_ctr; - break; - case NID_aes_192_ctr: - *cipher = &pk11_aes_192_ctr; - break; - case NID_aes_256_ctr: - *cipher = &pk11_aes_256_ctr; - break; - case NID_bf_cbc: - *cipher = &pk11_bf_cbc; - break; - case NID_rc4: - *cipher = &pk11_rc4; - break; - default: - *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; - /* - * A special case. For "openssl dgst -dss1 -engine pkcs11 ...", - * OpenSSL calls EVP_get_digestbyname() on "dss1" which ends up - * calling pk11_engine_digests() for NID_dsa. Internally, if an - * engine is not used, OpenSSL uses SHA1_Init() as expected for - * DSA. So, we must return pk11_sha1() for NID_dsa as well. Note - * that this must have changed between 0.9.8 and 1.0.0 since we - * did not have the problem with the 0.9.8 version. - */ - case NID_sha1: - case NID_dsa: - *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; - - if (from->md_data == NULL || to->digest->ctx_size == 0) - return (1); - - /* The copy-from state */ - state = (PK11_CIPHER_STATE *) from->md_data; - if (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_pubkey_slot_sofar; - CK_SLOT_ID current_slot = 0; - int best_number_of_mechs = 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); - - pubkey_SLOTID = pSlotList[0]; - for (i = 0; i < ulSlotCount; i++) - { - current_slot = pSlotList[i]; - - DEBUG_SLOT_SEL("%s: == checking slot: %d ==\n", PK11_DBG, - current_slot); - 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); - pk11_choose_rand_slot(token_info, current_slot); - - pk11_choose_pubkey_slot(mech_info, token_info, current_slot, - rv, best_number_of_mechs, best_pubkey_slot_sofar); - - (void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids)); - (void) memset(local_digest_nids, 0, sizeof (local_digest_nids)); - pk11_choose_cipher_digest(local_cipher_nids, - local_digest_nids, pFuncList, current_slot); - } - - if (best_number_of_mechs == 0) - { - DEBUG_SLOT_SEL("%s: no rsa/dsa/dh\n", PK11_DBG); - } - else - { - pubkey_SLOTID = best_pubkey_slot_sofar; - } - - 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_choose_rand_slot(CK_TOKEN_INFO token_info, - CK_SLOT_ID current_slot) - { - DEBUG_SLOT_SEL("%s: checking rand slots\n", PK11_DBG); - - if (((token_info.flags & CKF_RNG) != 0) && !pk11_have_random) - { - DEBUG_SLOT_SEL( - "%s: this token has CKF_RNG flag\n", PK11_DBG); - pk11_have_random = CK_TRUE; - rand_SLOTID = current_slot; - } - } - -static void pk11_choose_pubkey_slot(CK_MECHANISM_INFO mech_info, - CK_TOKEN_INFO token_info, CK_SLOT_ID current_slot, CK_RV rv, - int best_number_of_mechs, CK_SLOT_ID best_pubkey_slot_sofar) - { - CK_BBOOL slot_has_rsa = CK_FALSE; - CK_BBOOL slot_has_dsa = CK_FALSE; - CK_BBOOL slot_has_dh = CK_FALSE; - int current_number_of_mechs = 0; - DEBUG_SLOT_SEL("%s: checking pubkey slots\n", PK11_DBG); - -#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; - current_number_of_mechs++; - } - } -#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; - current_number_of_mechs++; - } - -#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; - current_number_of_mechs++; - } - } -#endif /* OPENSSL_NO_DH */ - - if (current_number_of_mechs > best_number_of_mechs) - { - best_pubkey_slot_sofar = current_slot; - pk11_have_rsa = slot_has_rsa; - pk11_have_dsa = slot_has_dsa; - pk11_have_dh = slot_has_dh; - best_number_of_mechs = current_number_of_mechs; - /* - * 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: pubkey flags changed to " - "%lu.\n", PK11_DBG, pubkey_token_flags); - } - } - -static void pk11_choose_cipher_digest(int *local_cipher_nids, - int *local_digest_nids, CK_FUNCTION_LIST_PTR pflist, - CK_SLOT_ID current_slot) - { - int current_slot_n_cipher = 0; - int current_slot_n_digest = 0; - - DEBUG_SLOT_SEL("%s: checking cipher/digest\n", PK11_DBG); - - pk11_find_symmetric_ciphers(pFuncList, current_slot, - ¤t_slot_n_cipher, local_cipher_nids); - - pk11_find_digests(pFuncList, current_slot, - ¤t_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); - - /* - * 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) > - (cipher_count + digest_count)) - { - DEBUG_SLOT_SEL("%s: changing best slot to %d\n", - PK11_DBG, current_slot); - SLOTID = current_slot; - cipher_count = current_slot_n_cipher; - digest_count = current_slot_n_digest; - OPENSSL_assert(cipher_count <= PK11_CIPHER_MAX); - OPENSSL_assert(digest_count <= PK11_DIGEST_MAX); - (void) memcpy(cipher_nids, local_cipher_nids, - sizeof (int) * cipher_count); - (void) memcpy(digest_nids, local_digest_nids, - sizeof (int) * digest_count); - } - } - -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) - { - static CK_MECHANISM_INFO mech_info; - static CK_RV rv; - static CK_MECHANISM_TYPE last_checked_mech = (CK_MECHANISM_TYPE)-1; - - OPENSSL_assert(cipher->mech_type != (CK_MECHANISM_TYPE)-1); - - DEBUG_SLOT_SEL("%s: checking mech: %x", PK11_DBG, cipher->mech_type); - if (cipher->mech_type != last_checked_mech) - { - rv = pflist->C_GetMechanismInfo(slot_id, cipher->mech_type, - &mech_info); - } - - last_checked_mech = cipher->mech_type; - - 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; - } - -/* 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 unless the mechanism is - * supported directly in a CPU instruction set. The table may be NULL (i.e., - * non-existent). - */ -static int nid_in_table(int nid, int *nid_table) - { - int i = 0; - - /* - * Special case first. 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 */ diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11.h --- a/components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11.h Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,257 +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 - * licensing@OpenSSL.org. - * - * 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 - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef E_PK11_H -#define E_PK11_H - -#include "e_pk11_err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* max byte length of a symmetric 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 split 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 int pk11_engine_pkey_methods(ENGINE *e, EVP_PKEY_METHOD **pmeth, - const int **nids, int nid); - -extern CK_FUNCTION_LIST_PTR pFuncList; - -#ifdef __cplusplus -} -#endif -#endif /* E_PK11_H */ diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_err.c --- a/components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_err.c Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,307 +0,0 @@ -/* - * Copyright (c) 2004, 2013, 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 - * licensing@OpenSSL.org. - * - * 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 - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#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); - } diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_err.h --- a/components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_err.h Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,236 +0,0 @@ -/* - * Copyright (c) 2004, 2013, 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 - * licensing@OpenSSL.org. - * - * 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 - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#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 */ diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_pub.c --- a/components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_pub.c Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3274 +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 - * licensing@OpenSSL.org. - * - * 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 - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#ifndef OPENSSL_NO_RSA -#include -#endif /* OPENSSL_NO_RSA */ -#ifndef OPENSSL_NO_DSA -#include -#endif /* OPENSSL_NO_DSA */ -#ifndef OPENSSL_NO_DH -#include -#endif /* OPENSSL_NO_DH */ -#include -#include -#include -#include -#include - -#ifndef OPENSSL_NO_HW -#ifndef OPENSSL_NO_HW_PK11 - -#include -#include -#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, const 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); - -static int pk11_pkey_meth_nids[] = {NID_dsa}; - -/* 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 */ - /* Internal rsa_keygen will be used if this is NULL. */ - NULL /* rsa_keygen */ - }; - -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 -/* - * Similar 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 caught 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 = ¶meter; - - 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, const 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 = ¶meter; - 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, - (CK_BYTE_PTR)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); - } - -/* - * OpenSSL 1.0.0 introduced ENGINE API for the PKEY EVP functions. Sadly, - * "openssl dgst -dss1 ..." now uses a new function EVP_DigestSignInit() which - * internally needs a PKEY method for DSA even when in the engine. So, to avoid - * a regression when moving from 0.9.8 to 1.0.0, we use an internal OpenSSL - * structure for the DSA PKEY methods to make it work. It is a future project to - * make it work with HW acceleration. - * - * Note that at the time of 1.0.0d release there is no documentation as to how - * the PKEY EVP functions are to be implemented in an engine. There is only one - * engine shipped with 1.0.0d that uses the PKEY EVP methods, the GOST engine. - * It was used as an example when fixing the above mentioned regression problem. - */ -int -pk11_engine_pkey_methods(ENGINE *e, EVP_PKEY_METHOD **pmeth, const int **nids, - int nid) - { - if (pmeth == NULL) - { - *nids = pk11_pkey_meth_nids; - return (1); - } - - switch (nid) - { - case NID_dsa: - *pmeth = (EVP_PKEY_METHOD *)EVP_PKEY_meth_find(nid); - return (1); - } - - /* Error branch. */ - *pmeth = NULL; - return (0); - } - -#endif /* OPENSSL_NO_HW_PK11 */ -#endif /* OPENSSL_NO_HW */ diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_uri.c --- a/components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_uri.c Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,888 +0,0 @@ -/* - * Copyright (c) 2004, 2015, 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 - * licensing@OpenSSL.org. - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifndef OPENSSL_NO_HW -#ifndef OPENSSL_NO_HW_PK11 - -#include -#include -#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 */ diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_uri.h --- a/components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_uri.h Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2004, 2013, 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 - * licensing@OpenSSL.org. - * - * 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 - -/* 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 */ diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1-fips-140/llib-lcrypto --- a/components/openssl/openssl-1.0.1-fips-140/llib-lcrypto Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +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, 2013, Oracle and/or its affiliates. All rights reserved. - */ - -/* LINTLIBRARY */ -/* PROTOLIB1 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1-fips-140/llib-lssl --- a/components/openssl/openssl-1.0.1-fips-140/llib-lssl Fri Aug 28 07:46:44 2015 -0700 +++ /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 -#include -#include -#include diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1-fips-140/openssl-1.0.1-fips-140.license --- a/components/openssl/openssl-1.0.1-fips-140/openssl-1.0.1-fips-140.license Fri Aug 28 07:46:44 2015 -0700 +++ /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 openssl-core@openssl.org. - - OpenSSL License - --------------- - -/* ==================================================================== - * Copyright (c) 1998-2011 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 - * openssl-core@openssl.org. - * - * 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 - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - - Original SSLeay License - ----------------------- - -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * 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 (tjh@cryptsoft.com). - * - * 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 (eay@cryptsoft.com)" - * 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 (tjh@cryptsoft.com)" - * - * 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.] - */ - diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1-fips-140/openssl-1.0.1-fips-140.p5m --- a/components/openssl/openssl-1.0.1-fips-140/openssl-1.0.1-fips-140.p5m Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,220 +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, 2015, Oracle and/or its affiliates. All rights reserved. -# - - default mangler.man.stability uncommitted> - -# 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. - \ - set action.hash $(MACH32)/include/openssl/%<1> > -set name=pkg.fmri \ - value=pkg:/library/security/openssl/openssl-fips-140@$(IPS_COMPONENT_VERSION),$(BUILD_VERSION) -set name=pkg.summary value="FIPS 140-2 Capable OpenSSL libraries" -set name=pkg.human-version value=$(COMPONENT_VERSION) -set name=pkg.linted.pkglint.dupaction001.1 value=true - -# This line is needed temporarily to workaround the link check error due to -# change of action type. It should be removed once non-FIPS version becomes -# available in the reference repository -set name=pkg.linted.pkglint.dupaction010.1 value=true -set name=pkg.linted.pkglint.dupaction010.2 value=true -set name=com.oracle.info.description \ - value="the FIPS 140-2 Capable OpenSSL libraries" -set name=com.oracle.info.tpno value=$(TPNO) -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. -file etc/openssl/openssl.cnf path=etc/openssl/fips-140/openssl.cnf group=sys \ - mode=0644 preserve=true -link path=lib/$(MACH64)/libcrypto.so.1.0.0 \ - target=../openssl/fips-140/$(MACH64)/libcrypto.so.1.0.0 mediator=openssl \ - mediator-implementation=fips-140 -link path=lib/$(MACH64)/libssl.so.1.0.0 \ - target=../openssl/fips-140/$(MACH64)/libssl.so.1.0.0 mediator=openssl \ - mediator-implementation=fips-140 -link path=lib/$(MACH64)/llib-lcrypto \ - target=../openssl/fips-140/$(MACH64)/llib-lcrypto mediator=openssl \ - mediator-implementation=fips-140 -link path=lib/$(MACH64)/llib-lcrypto.ln \ - target=../openssl/fips-140/$(MACH64)/llib-lcrypto.ln mediator=openssl \ - mediator-implementation=fips-140 -link path=lib/$(MACH64)/llib-lssl \ - target=../openssl/fips-140/$(MACH64)/llib-lssl mediator=openssl \ - mediator-implementation=fips-140 -link path=lib/$(MACH64)/llib-lssl.ln \ - target=../openssl/fips-140/$(MACH64)/llib-lssl.ln mediator=openssl \ - mediator-implementation=fips-140 - -# Mediator links for 32-bit libraries -link path=lib/libcrypto.so.1.0.0 target=openssl/fips-140/libcrypto.so.1.0.0 \ - mediator=openssl mediator-implementation=fips-140 -link path=lib/libssl.so.1.0.0 target=openssl/fips-140/libssl.so.1.0.0 \ - mediator=openssl mediator-implementation=fips-140 -link path=lib/llib-lcrypto target=openssl/fips-140/llib-lcrypto \ - mediator=openssl mediator-implementation=fips-140 -link path=lib/llib-lcrypto.ln target=openssl/fips-140/llib-lcrypto.ln \ - mediator=openssl mediator-implementation=fips-140 -link path=lib/llib-lssl target=openssl/fips-140/llib-lssl mediator=openssl \ - mediator-implementation=fips-140 -link path=lib/llib-lssl.ln target=openssl/fips-140/llib-lssl.ln \ - mediator=openssl mediator-implementation=fips-140 - -# Mediator links for 64-bit libraries -link path=lib/openssl/engines/$(MACH64)/libpk11.so.1 \ - target=../../fips-140/engines/$(MACH64)/libpk11.so.1 mediator=openssl \ - mediator-implementation=fips-140 -link path=lib/openssl/engines/libpk11.so.1 \ - target=../fips-140/engines/libpk11.so.1 mediator=openssl \ - mediator-implementation=fips-140 -file $(MACH32)/apps/openssl path=lib/openssl/fips-140/$(MACH32)/openssl \ - owner=root group=bin mode=0555 -link path=lib/openssl/fips-140/$(MACH64)/libcrypto.so target=libcrypto.so.1.0.0 - -# 64 bit libraries, lint libraries, and engines. -file $(MACH64)/libcrypto.so.1.0.0 \ - path=lib/openssl/fips-140/$(MACH64)/libcrypto.so.1.0.0 -link path=lib/openssl/fips-140/$(MACH64)/libssl.so target=libssl.so.1.0.0 -file $(MACH64)/libssl.so.1.0.0 \ - path=lib/openssl/fips-140/$(MACH64)/libssl.so.1.0.0 -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 -link path=lib/openssl/fips-140/64 target=$(MACH64) -file etc/openssl/misc/CA.pl path=lib/openssl/fips-140/CA.pl -link path=lib/openssl/fips-140/engines/$(MACH64)/libpk11.so target=libpk11.so.1 -file $(MACH64)/engines/libpk11.so \ - path=lib/openssl/fips-140/engines/$(MACH64)/libpk11.so.1 -link path=lib/openssl/fips-140/engines/libpk11.so target=libpk11.so.1 - -# 32 bit libraries, lint libraries, and engines. -file $(MACH32)/engines/libpk11.so path=lib/openssl/fips-140/engines/libpk11.so.1 -link path=lib/openssl/fips-140/libcrypto.so target=libcrypto.so.1.0.0 -file $(MACH32)/libcrypto.so.1.0.0 path=lib/openssl/fips-140/libcrypto.so.1.0.0 -link path=lib/openssl/fips-140/libssl.so target=libssl.so.1.0.0 -file $(MACH32)/libssl.so.1.0.0 path=lib/openssl/fips-140/libssl.so.1.0.0 -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 - -# Commands. -file $(MACH64)/apps/openssl path=lib/openssl/fips-140/openssl owner=root \ - group=bin mode=0555 -link path=usr/bin/$(MACH32)/openssl \ - target=../../../lib/openssl/fips-140/$(MACH32)/openssl mediator=openssl \ - mediator-implementation=fips-140 -link path=usr/bin/CA.pl target=../../lib/openssl/fips-140/CA.pl \ - mediator=openssl mediator-implementation=fips-140 - -# Mediator links for the commands -link path=usr/bin/openssl target=../../lib/openssl/fips-140/openssl \ - mediator=openssl mediator-implementation=fips-140 -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/cmac.h -file path=usr/include/openssl/fips-140/openssl/cms.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/ec.h -file path=usr/include/openssl/fips-140/openssl/ecdh.h -file path=usr/include/openssl/fips-140/openssl/ecdsa.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/modes.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/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/srp.h -file path=usr/include/openssl/fips-140/openssl/srtp.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/symhacks.h -file path=usr/include/openssl/fips-140/openssl/tls1.h -file path=usr/include/openssl/fips-140/openssl/ts.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/whrlpool.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-1.0.1-fips-140.license license="OpenSSL, SSLeay" - -# OpenSSL packages are now managed by 'pkg mediator', and the installation -# of 'openssl-fips-140' package requires 'openssl' package with the mediator -# change (s12_build42 or later) -depend type=optional fmri=library/security/openssl@1.0.1.6,5.12-5.12.0.0.0.42.0 diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1-fips-140/patches-post-config/opensslconf.patch --- a/components/openssl/openssl-1.0.1-fips-140/patches-post-config/opensslconf.patch Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ ---- /tmp/opensslconf.h Fri Feb 11 15:36:12 2011 -+++ openssl-1.0.0d/crypto/opensslconf.h Fri Feb 11 16:58:36 2011 -@@ -181,7 +181,11 @@ - - #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" -+#endif - #define OPENSSLDIR "/etc/openssl" - #endif - #endif -@@ -228,21 +232,39 @@ - /* 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 -+/* -+ * OpenSSL revision 1.521 from 2005-12-15 in OpenSSL_1_0_0-stable branch changed -+ * 64 bit sparcv9 configuration from SIXTY_FOUR_BIT_LONG to BN_LLONG. -+ */ -+#if defined(__x86_64) -+#undef BN_LLONG -+#else - #define BN_LLONG -+#endif - - /* Should we define BN_DIV2W here? */ - - /* Only one for the following should be defined */ -+#if 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 -+#endif - - #if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) - #define CONFIG_HEADER_RC4_LOCL_H diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1-fips-140/patches/201-openssl_fips.patch --- a/components/openssl/openssl-1.0.1-fips-140/patches/201-openssl_fips.patch Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -# -# Patch developed in-house. Solaris-specific; not suitable for upstream. -# ---- openssl-0.9.8m/apps/openssl.c Thu Oct 15 19:28:02 2009 -+++ openssl-0.9.8m/apps/openssl.c Fri Feb 26 16:12:30 2010 -@@ -135,6 +135,9 @@ - # include - #endif - -+/* Solaris OpenSSL */ -+#include -+ - /* - * The LHASH callbacks ("hash" & "cmp") have been replaced by functions with - * the base prototypes (we cast each variable inside the function to the -@@ -155,9 +158,10 @@ - BIO *bio_err = NULL; - #endif - -+static int *modes; -+ - static void lock_dbg_cb(int mode, int type, const char *file, int line) - { -- static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ - const char *errstr = NULL; - int rw; - -@@ -167,7 +168,7 @@ - goto err; - } - -- if (type < 0 || type >= CRYPTO_NUM_LOCKS) { -+ if (type < 0 || type >= CRYPTO_num_locks()) { - errstr = "type out of bounds"; - goto err; - } -@@ -305,6 +306,14 @@ - if (getenv("OPENSSL_DEBUG_LOCKING") != NULL) - #endif - { -+ modes = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (int)); -+ if (modes == NULL) { -+ ERR_load_crypto_strings(); -+ BIO_printf(bio_err,"Memory allocation failure\n"); -+ ERR_print_errors(bio_err); -+ EXIT(1); -+ } -+ memset(modes, 0, CRYPTO_num_locks() * sizeof (int)); - CRYPTO_set_locking_callback(lock_dbg_cb); - } - -@@ -308,18 +320,28 @@ - CRYPTO_set_locking_callback(lock_dbg_cb); - } - -+/* -+ * Solaris OpenSSL -+ * Add a further check for the FIPS_mode_set() symbol before calling to -+ * allow openssl(1openssl) to be run against both fips and non-fips libraries. -+ */ - if (getenv("OPENSSL_FIPS")) { --#ifdef OPENSSL_FIPS -- if (!FIPS_mode_set(1)) { -+ -+ int (*FIPS_mode_set)(int); -+ FIPS_mode_set = (int (*)(int)) dlsym(RTLD_NEXT, "FIPS_mode_set"); -+ -+ if (FIPS_mode_set != NULL) { -+ if (!(*FIPS_mode_set)(1)) { - ERR_load_crypto_strings(); - ERR_print_errors(BIO_new_fp(stderr, BIO_NOCLOSE)); - EXIT(1); - } --#else -- fprintf(stderr, "FIPS mode not supported.\n"); -+ } else { -+ fprintf(stderr, "Failed to enable FIPS mode. " -+ "For more information about running in FIPS mode see openssl(5).\n"); - EXIT(1); --#endif - } -+ } - - apps_startup(); - diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1-fips-140/patches/202-17952966.patch --- a/components/openssl/openssl-1.0.1-fips-140/patches/202-17952966.patch Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -Solaris-specific; not suitable for upstream - ---- /tmp/Makefile.shared Mon Feb 14 14:39:29 2011 -+++ openssl-1.0.0d/Makefile.shared Mon Feb 14 14:50:52 2011 -@@ -108,7 +108,7 @@ - LD_LIBRARY_PATH=$$LIBPATH:$$LD_LIBRARY_PATH \ - $${SHAREDCMD} $${SHAREDFLAGS} \ - -o $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX \ -- $$ALLSYMSFLAGS $$SHOBJECTS $$NOALLSYMSFLAGS $$LIBDEPS \ -+ $$ALLSYMSFLAGS $$SHOBJECTS $$NOALLSYMSFLAGS $$LIBDEPS -lc \ - ) && $(SYMLINK_SO) - - SYMLINK_SO= \ diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1/Makefile --- a/components/openssl/openssl-1.0.1/Makefile Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,423 +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, 2015, Oracle and/or its affiliates. All rights reserved. -# -include ../../../make-rules/shared-macros.mk - -COMPONENT_NAME = openssl -# When new version of OpenSSL comes in, you must update both COMPONENT_VERSION -# and IPS_COMPONENT_VERSION. -# When upgrading OpenSSL, please, DON'T FORGET TO TEST WANBOOT too. -# For more information about wanboot-openssl testing, please refer to -# ../README. -COMPONENT_VERSION = 1.0.1p -# Version for IPS. It is easier to do it manually than convert the letter to a -# number while taking into account that there might be no letter at all. -IPS_COMPONENT_VERSION = 1.0.1.16 -COMPONENT_PROJECT_URL= http://www.openssl.org/ -COMPONENT_SRC = $(COMPONENT_NAME)-$(COMPONENT_VERSION) -COMPONENT_ARCHIVE = $(COMPONENT_SRC).tar.gz -COMPONENT_ARCHIVE_HASH= \ - sha256:bd5ee6803165c0fb60bbecbacacf244f1f90d2aa0d71353af610c29121e9b2f1 -COMPONENT_ARCHIVE_URL = $(COMPONENT_PROJECT_URL)source/$(COMPONENT_ARCHIVE) -COMPONENT_BUGDB= library/openssl - -TPNO= 23452 - -# Clone the patch files to the patches-all dir. -# COPY_COMMON_FILES is there so that rsync is called as soon as -# the Makefile is parsed. -PATCH_DIR=patches-all -CLEAN_PATHS += $(PATCH_DIR) -COPY_COMMON_FILES:= $(shell rsync -ac ../common/patches/ patches/ $(PATCH_DIR)) - -include $(WS_MAKE_RULES)/prep.mk -include $(WS_MAKE_RULES)/configure.mk -include $(WS_MAKE_RULES)/ips.mk -include $(WS_MAKE_RULES)/lint-libraries.mk - -PATH=$(SPRO_VROOT)/bin:/usr/bin:/usr/gnu/bin:/usr/perl5/bin -ifeq ($(strip $(PARFAIT_BUILD)),yes) -PATH=$(PARFAIT_TOOLS):$(SPRO_VROOT)/bin:/usr/bin:/usr/perl5/bin -endif - -# Variant of OpenSSL for wanboot is built in build/sparcv9-wanboot. -BUILD_DIR_WANBOOT = $(BUILD_DIR)/$(MACH64)-wanboot - -# OpenSSL does not use autoconf but its own configure system. -CONFIGURE_SCRIPT = $(SOURCE_DIR)/Configure - -# This is to force OpenSSL's Configure script to use gmake for 'make links'. -# Otherwise it fails with: -# mksh: Fatal error in reader: Unmatched `(' on line -CONFIGURE_ENV += MAKE="$(GMAKE)" - -# 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 - -# Configure options common to both regular OpenSSL and OpenSSL for wanboot. -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 - -# MD2 is not enabled by default in OpensSSL but some software we have in -# Userland needs it. One example is nmap. -CONFIGURE_OPTIONS += enable-md2 -CONFIGURE_OPTIONS += no-seed - -# Disable SSLv2 and SSLv3 protocols -CONFIGURE_OPTIONS += no-ssl2 -CONFIGURE_OPTIONS += no-ssl3 - -# We use both no-whirlpool and no-whrlpool since there is an inconsistency in -# the OpenSSL code and one needs both to build OpenSSL successfully with -# Whirlpool implementation removed. -CONFIGURE_OPTIONS += no-whirlpool -CONFIGURE_OPTIONS += no-whrlpool - -# Some additional options needed for our engines. -CONFIGURE_OPTIONS += --pk11-libname=$(PKCS11_LIB$(BITS)) -CONFIGURE_OPTIONS += --enginesdir=$(ENGINESDIR_$(BITS)) - -# 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-sparcv9-cc-sunw -CONFIGURE_OPTIONS64_i386 = solaris64-x86_64-cc-sunw -CONFIGURE_OPTIONS64_sparc = solaris64-sparcv9-cc-sunw - -# Options specific to regular build. -# They must not be specified as common, as they cannot be overridden. -$(BUILD_DIR)/$(MACH32)/.configured: CONFIGURE_OPTIONS += threads -$(BUILD_DIR)/$(MACH64)/.configured: CONFIGURE_OPTIONS += threads -$(BUILD_DIR)/$(MACH32)/.configured: CONFIGURE_OPTIONS += shared -$(BUILD_DIR)/$(MACH64)/.configured: CONFIGURE_OPTIONS += shared -$(BUILD_DIR)/$(MACH32)/.configured: CONFIGURE_OPTIONS += shared -$(BUILD_DIR)/$(MACH64)/.configured: CONFIGURE_OPTIONS += shared -$(BUILD_DIR)/$(MACH32)/.configured: CONFIGURE_OPTIONS += \ - $(CONFIGURE_OPTIONS32_$(MACH)) -$(BUILD_DIR)/$(MACH64)/.configured: CONFIGURE_OPTIONS += \ - $(CONFIGURE_OPTIONS64_$(MACH)) - -# OpenSSL for wanboot specific options -$(BUILD_DIR_WANBOOT)/.configured: BITS=64 -$(BUILD_DIR_WANBOOT)/.configured: CONFIGURE_OPTIONS += -DNO_CHMOD -$(BUILD_DIR_WANBOOT)/.configured: CONFIGURE_OPTIONS += -D_BOOT -$(BUILD_DIR_WANBOOT)/.configured: CONFIGURE_OPTIONS += -DOPENSSL_NO_DTLS1 -$(BUILD_DIR_WANBOOT)/.configured: CONFIGURE_OPTIONS += -DOPENSSL_NO_HEARTBEATS -$(BUILD_DIR_WANBOOT)/.configured: CONFIGURE_OPTIONS += -DOPENSSL_NO_SRP -$(BUILD_DIR_WANBOOT)/.configured: CONFIGURE_OPTIONS += no-cast -$(BUILD_DIR_WANBOOT)/.configured: CONFIGURE_OPTIONS += no-dso -$(BUILD_DIR_WANBOOT)/.configured: CONFIGURE_OPTIONS += no-rc4 -$(BUILD_DIR_WANBOOT)/.configured: CONFIGURE_OPTIONS += no-ripemd -$(BUILD_DIR_WANBOOT)/.configured: CONFIGURE_OPTIONS += no-hw -$(BUILD_DIR_WANBOOT)/.configured: CONFIGURE_OPTIONS += no-threads -$(BUILD_DIR_WANBOOT)/.configured: CONFIGURE_OPTIONS += no-shared -$(BUILD_DIR_WANBOOT)/.configured: CONFIGURE_OPTIONS += \ - solaris64-sparcv9-cc-sunw-wanboot - -# 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. So, we must get the full source code into the -# build directory. -COMPONENT_PRE_CONFIGURE_ACTION = \ - ( $(CLONEY) $(SOURCE_DIR) $(BUILD_DIR)/$(MACH$(BITS)); ) - -$(BUILD_DIR_WANBOOT)/.configured: COMPONENT_PRE_CONFIGURE_ACTION = \ - ( $(CLONEY) $(SOURCE_DIR) $(BUILD_DIR_WANBOOT); ) - -# 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 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. -# Same holds for wanboot-stubs.c, which stubs out several functions, that are -# not available in the stand-alone environment of wanboot. -COMPONENT_PRE_BUILD_ACTION = \ - ( echo "Cloning engines..."; \ - $(LN) -fs $(COMPONENT_DIR)/engines/pkcs11/*.[ch] $(@D)/engines; \ - $(LN) -fs $(COMPONENT_DIR)/wanboot-openssl/wanboot-stubs.c $(@D)/crypto; \ - $(LN) -fs $(COMPONENT_DIR)/inline-t4/sparc_arch.h $(@D)/crypto/; \ - $(LN) -fs $(COMPONENT_DIR)/inline-t4/md5-sparcv9.pl $(@D)/crypto/md5/asm; \ - $(LN) -fs $(COMPONENT_DIR)/inline-t4/aest4-sparcv9.pl $(@D)/crypto/aes/asm; \ - $(LN) -fs $(COMPONENT_DIR)/inline-t4/dest4-sparcv9.pl $(@D)/crypto/des/asm; \ - $(LN) -fs $(COMPONENT_DIR)/inline-t4/sparcv9_modes.pl $(@D)/crypto/perlasm; \ - $(LN) -fs $(COMPONENT_DIR)/inline-t4/vis3-mont.pl $(@D)/crypto/bn/asm; \ - $(LN) -fs $(COMPONENT_DIR)/inline-t4/sparcv9-gf2m.pl $(@D)/crypto/bn/asm; \ - $(LN) -fs $(COMPONENT_DIR)/inline-t4/sparct4-mont.pl $(@D)/crypto/bn/asm; ) - -# Enable ASLR for this component -ASLR_MODE = $(ASLR_ENABLE) - -# OpenSSL for wanboot is built on sparc only. -ifeq ($(MACH), sparc) -BUILD_64 += $(BUILD_DIR_WANBOOT)/.built -endif - -configure: $(CONFIGURE_32_and_64) - -build: $(BUILD_32_and_64) - -# Object files for wanboot-openssl.o have to be listed explicitly. -WANBOOT_OBJS = \ - crypto/aes/aes-sparcv9.o crypto/aes/aes_cbc.o crypto/aes/aes_core.o \ - crypto/aes/aes_misc.o crypto/aes/aes_wrap.o crypto/aes/aest4-sparcv9.o \ - crypto/asn1/a_bitstr.o \ - crypto/asn1/a_bool.o crypto/asn1/a_bytes.o crypto/asn1/a_d2i_fp.o \ - crypto/asn1/a_digest.o crypto/asn1/a_dup.o crypto/asn1/a_enum.o \ - crypto/asn1/a_gentm.o crypto/asn1/a_i2d_fp.o crypto/asn1/a_int.o \ - crypto/asn1/a_mbstr.o crypto/asn1/a_object.o crypto/asn1/a_octet.o \ - crypto/asn1/a_print.o crypto/asn1/a_set.o crypto/asn1/a_sign.o \ - crypto/asn1/a_strex.o crypto/asn1/a_strnid.o crypto/asn1/a_time.o \ - crypto/asn1/a_type.o crypto/asn1/a_utctm.o crypto/asn1/a_utf8.o \ - crypto/asn1/a_verify.o crypto/asn1/ameth_lib.o crypto/asn1/asn1_err.o \ - crypto/asn1/asn1_gen.o crypto/asn1/asn1_lib.o crypto/asn1/asn1_par.o \ - crypto/asn1/asn_mime.o crypto/asn1/asn_pack.o crypto/asn1/bio_asn1.o \ - crypto/asn1/bio_ndef.o crypto/asn1/d2i_pr.o crypto/asn1/evp_asn1.o \ - crypto/asn1/f_int.o crypto/asn1/f_string.o crypto/asn1/i2d_pr.o \ - crypto/asn1/nsseq.o crypto/asn1/p5_pbe.o crypto/asn1/p5_pbev2.o \ - crypto/asn1/p8_pkey.o crypto/asn1/t_pkey.o crypto/asn1/t_x509.o \ - crypto/asn1/t_x509a.o crypto/asn1/tasn_dec.o crypto/asn1/tasn_enc.o \ - crypto/asn1/tasn_fre.o crypto/asn1/tasn_new.o crypto/asn1/tasn_prn.o \ - crypto/asn1/tasn_typ.o crypto/asn1/tasn_utl.o crypto/asn1/x_algor.o \ - crypto/asn1/x_attrib.o crypto/asn1/x_bignum.o crypto/asn1/x_crl.o \ - crypto/asn1/x_exten.o crypto/asn1/x_info.o crypto/asn1/x_long.o \ - crypto/asn1/x_name.o crypto/asn1/x_pkey.o crypto/asn1/x_pubkey.o \ - crypto/asn1/x_req.o crypto/asn1/x_sig.o crypto/asn1/x_spki.o \ - crypto/asn1/x_val.o crypto/asn1/x_x509.o crypto/asn1/x_x509a.o \ - crypto/bf/bf_cfb64.o crypto/bf/bf_ecb.o crypto/bf/bf_enc.o \ - crypto/bf/bf_ofb64.o crypto/bf/bf_skey.o crypto/bio/b_dump.o \ - crypto/bio/b_print.o crypto/bio/bf_buff.o crypto/bio/bio_err.o \ - crypto/bio/bio_lib.o crypto/bio/bss_file.o crypto/bio/bss_mem.o \ - crypto/bio/bss_null.o crypto/bio/bss_sock.o crypto/bn/bn-sparcv9.o \ - crypto/bn/bn_add.o crypto/bn/bn_blind.o crypto/bn/bn_ctx.o \ - crypto/bn/bn_div.o crypto/bn/bn_err.o crypto/bn/bn_exp.o \ - crypto/bn/bn_exp2.o crypto/bn/bn_gcd.o crypto/bn/bn_lib.o \ - crypto/bn/bn_mod.o crypto/bn/bn_mont.o crypto/bn/bn_mul.o \ - crypto/bn/bn_prime.o crypto/bn/bn_print.o crypto/bn/bn_rand.o \ - crypto/bn/bn_recp.o crypto/bn/bn_shift.o crypto/bn/bn_sqr.o \ - crypto/bn/bn_word.o crypto/bn/sparcv9-mont.o crypto/bn/sparcv9a-mont.o \ - crypto/bn/sparct4-mont.o crypto/bn/vis3-mont.o \ - crypto/buffer/buf_err.o crypto/buffer/buf_str.o crypto/buffer/buffer.o \ - crypto/camellia/camellia.o crypto/camellia/cmll_cbc.o \ - crypto/camellia/cmll_cfb.o crypto/camellia/cmll_ecb.o \ - crypto/camellia/cmll_misc.o crypto/camellia/cmll_ofb.o \ - crypto/camellia/cmll_utl.o crypto/cmac/cm_ameth.o crypto/cmac/cm_pmeth.o \ - crypto/cmac/cmac.o crypto/cms/cms_asn1.o crypto/cms/cms_att.o \ - crypto/cms/cms_dd.o crypto/cms/cms_enc.o crypto/cms/cms_env.o \ - crypto/cms/cms_err.o crypto/cms/cms_io.o crypto/cms/cms_lib.o \ - crypto/cms/cms_pwri.o crypto/cms/cms_sd.o crypto/comp/c_zlib.o \ - crypto/comp/comp_err.o crypto/comp/comp_lib.o crypto/conf/conf_api.o \ - crypto/conf/conf_def.o crypto/conf/conf_err.o crypto/conf/conf_lib.o \ - crypto/conf/conf_mod.o crypto/cpt_err.o crypto/cryptlib.o \ - crypto/des/cfb64ede.o crypto/des/cfb64enc.o crypto/des/cfb_enc.o \ - crypto/des/des_enc-sparc.o crypto/des/ecb3_enc.o crypto/des/ecb_enc.o \ - crypto/des/ofb64ede.o crypto/des/ofb64enc.o crypto/des/dest4-sparcv9.o \ - crypto/des/set_key.o \ - crypto/des/xcbc_enc.o crypto/dh/dh_ameth.o crypto/dh/dh_asn1.o \ - crypto/dh/dh_check.o crypto/dh/dh_err.o crypto/dh/dh_gen.o \ - crypto/dh/dh_key.o crypto/dh/dh_lib.o crypto/dh/dh_pmeth.o \ - crypto/dsa/dsa_ameth.o crypto/dsa/dsa_asn1.o crypto/dsa/dsa_err.o \ - crypto/dsa/dsa_gen.o crypto/dsa/dsa_key.o crypto/dsa/dsa_lib.o \ - crypto/dsa/dsa_ossl.o crypto/dsa/dsa_pmeth.o crypto/dsa/dsa_sign.o \ - crypto/dsa/dsa_vrf.o crypto/dso/dso_lib.o crypto/dso/dso_null.o \ - crypto/dso/dso_openssl.o crypto/engine/eng_ctrl.o crypto/engine/eng_err.o \ - crypto/engine/eng_init.o crypto/engine/eng_lib.o crypto/engine/eng_list.o \ - crypto/engine/eng_pkey.o crypto/engine/eng_table.o \ - crypto/engine/tb_asnmth.o crypto/engine/tb_cipher.o crypto/engine/tb_dh.o \ - crypto/engine/tb_digest.o crypto/engine/tb_dsa.o \ - crypto/engine/tb_pkmeth.o crypto/engine/tb_rand.o crypto/engine/tb_rsa.o \ - crypto/err/err.o crypto/err/err_all.o crypto/err/err_prn.o \ - crypto/evp/bio_b64.o crypto/evp/bio_enc.o crypto/evp/bio_md.o \ - crypto/evp/c_all.o crypto/evp/c_allc.o crypto/evp/c_alld.o \ - crypto/evp/digest.o crypto/evp/e_aes.o crypto/evp/e_aes_cbc_hmac_sha1.o \ - crypto/evp/e_bf.o crypto/evp/e_camellia.o crypto/evp/e_des.o \ - crypto/evp/e_des3.o crypto/evp/e_null.o crypto/evp/e_rc2.o \ - crypto/evp/e_xcbc_d.o crypto/evp/encode.o crypto/evp/evp_enc.o \ - crypto/evp/evp_err.o crypto/evp/evp_key.o crypto/evp/evp_lib.o \ - crypto/evp/evp_pbe.o crypto/evp/evp_pkey.o crypto/evp/m_dss.o \ - crypto/evp/m_dss1.o crypto/evp/m_md4.o crypto/evp/m_md5.o \ - crypto/evp/m_sha.o crypto/evp/m_sha1.o crypto/evp/m_sigver.o \ - crypto/evp/names.o crypto/evp/p5_crpt.o crypto/evp/p5_crpt2.o \ - crypto/evp/p_lib.o crypto/evp/p_sign.o crypto/evp/p_verify.o \ - crypto/evp/pmeth_fn.o crypto/evp/pmeth_gn.o crypto/evp/pmeth_lib.o \ - crypto/ex_data.o crypto/hmac/hm_ameth.o crypto/hmac/hm_pmeth.o \ - crypto/hmac/hmac.o crypto/lhash/lhash.o crypto/md4/md4_dgst.o \ - crypto/md5/md5-sparcv9.o \ - crypto/md5/md5_dgst.o crypto/mem.o crypto/mem_dbg.o crypto/modes/cbc128.o \ - crypto/modes/ccm128.o crypto/modes/cfb128.o crypto/modes/ctr128.o \ - crypto/modes/gcm128.o crypto/modes/ghash-sparcv9.o crypto/modes/ofb128.o \ - crypto/modes/xts128.o crypto/o_dir.o crypto/o_init.o crypto/o_time.o \ - crypto/objects/o_names.o crypto/objects/obj_dat.o \ - crypto/objects/obj_err.o crypto/objects/obj_lib.o \ - crypto/objects/obj_xref.o crypto/ocsp/ocsp_asn.o crypto/ocsp/ocsp_err.o \ - crypto/pem/pem_all.o crypto/pem/pem_err.o crypto/pem/pem_info.o \ - crypto/pem/pem_lib.o crypto/pem/pem_oth.o crypto/pem/pem_pk8.o \ - crypto/pem/pem_pkey.o crypto/pem/pem_x509.o crypto/pem/pem_xaux.o \ - crypto/pkcs12/p12_add.o crypto/pkcs12/p12_asn.o crypto/pkcs12/p12_attr.o \ - crypto/pkcs12/p12_crpt.o crypto/pkcs12/p12_decr.o crypto/pkcs12/p12_key.o \ - crypto/pkcs12/p12_mutl.o crypto/pkcs12/p12_p8d.o crypto/pkcs12/p12_p8e.o \ - crypto/pkcs12/p12_utl.o crypto/pkcs12/pk12err.o crypto/pkcs7/pk7_asn1.o \ - crypto/pkcs7/pk7_attr.o crypto/pkcs7/pk7_doit.o crypto/pkcs7/pk7_lib.o \ - crypto/pkcs7/pkcs7err.o crypto/pqueue/pqueue.o crypto/rand/md_rand.o \ - crypto/rand/rand_err.o crypto/rand/rand_lib.o crypto/rand/rand_unix.o \ - crypto/rand/randfile.o crypto/rc2/rc2_cbc.o crypto/rc2/rc2_ecb.o \ - crypto/rc2/rc2_skey.o crypto/rc2/rc2cfb64.o crypto/rc2/rc2ofb64.o \ - crypto/rsa/rsa_ameth.o crypto/rsa/rsa_asn1.o crypto/rsa/rsa_crpt.o \ - crypto/rsa/rsa_eay.o crypto/rsa/rsa_err.o crypto/rsa/rsa_gen.o \ - crypto/rsa/rsa_lib.o crypto/rsa/rsa_none.o crypto/rsa/rsa_oaep.o \ - crypto/rsa/rsa_pk1.o crypto/rsa/rsa_pmeth.o crypto/rsa/rsa_pss.o \ - crypto/rsa/rsa_saos.o crypto/rsa/rsa_sign.o crypto/rsa/rsa_ssl.o \ - crypto/rsa/rsa_x931.o crypto/sha/sha1-sparcv9.o crypto/sha/sha1dgst.o \ - crypto/sha/sha256-sparcv9.o crypto/sha/sha256.o \ - crypto/sha/sha512-sparcv9.o crypto/sha/sha512.o crypto/sha/sha_dgst.o \ - crypto/sparccpuid.o crypto/sparcv9cap.o crypto/srp/srp_lib.o \ - crypto/srp/srp_vfy.o crypto/stack/stack.o crypto/ts/ts_err.o \ - crypto/txt_db/txt_db.o crypto/ui/ui_err.o crypto/wanboot-stubs.o \ - crypto/x509/by_dir.o crypto/x509/by_file.o crypto/x509/x509_att.o \ - crypto/x509/x509_cmp.o crypto/x509/x509_d2.o crypto/x509/x509_def.o \ - crypto/x509/x509_err.o crypto/x509/x509_ext.o crypto/x509/x509_lu.o \ - crypto/x509/x509_obj.o crypto/x509/x509_req.o crypto/x509/x509_trs.o \ - crypto/x509/x509_txt.o crypto/x509/x509_v3.o crypto/x509/x509_vfy.o \ - crypto/x509/x509_vpm.o crypto/x509/x509name.o crypto/x509/x509rset.o \ - crypto/x509/x509type.o crypto/x509/x_all.o crypto/x509v3/pcy_cache.o \ - crypto/x509v3/pcy_data.o crypto/x509v3/pcy_lib.o crypto/x509v3/pcy_map.o \ - crypto/x509v3/pcy_node.o crypto/x509v3/pcy_tree.o crypto/x509v3/v3_akey.o \ - crypto/x509v3/v3_akeya.o crypto/x509v3/v3_alt.o crypto/x509v3/v3_bcons.o \ - crypto/x509v3/v3_bitst.o crypto/x509v3/v3_conf.o crypto/x509v3/v3_cpols.o \ - crypto/x509v3/v3_crld.o crypto/x509v3/v3_enum.o crypto/x509v3/v3_extku.o \ - crypto/x509v3/v3_genn.o crypto/x509v3/v3_ia5.o crypto/x509v3/v3_info.o \ - crypto/x509v3/v3_int.o crypto/x509v3/v3_lib.o crypto/x509v3/v3_ncons.o \ - crypto/x509v3/v3_ocsp.o crypto/x509v3/v3_pci.o crypto/x509v3/v3_pcia.o \ - crypto/x509v3/v3_pcons.o crypto/x509v3/v3_pku.o crypto/x509v3/v3_pmaps.o \ - crypto/x509v3/v3_prn.o crypto/x509v3/v3_purp.o crypto/x509v3/v3_skey.o \ - crypto/x509v3/v3_sxnet.o crypto/x509v3/v3_utl.o crypto/x509v3/v3err.o \ - ssl/s3_both.o ssl/s3_clnt.o ssl/s3_enc.o ssl/s3_lib.o ssl/s3_pkt.o \ - ssl/ssl_algs.o ssl/ssl_asn1.o ssl/ssl_cert.o ssl/ssl_ciph.o ssl/ssl_err.o \ - ssl/ssl_err2.o ssl/ssl_lib.o ssl/ssl_rsa.o ssl/ssl_sess.o ssl/t1_enc.o \ - ssl/t1_lib.o ssl/t1_reneg.o ssl/d1_srtp.o ssl/s3_cbc.o ssl/t1_clnt.o - - - -# Linking of openssl bits for wanboot. -# Interface for wanboot is specified in mapfile.wanboot. Object files are -# compiled to have functions in separate sections, unused sections get -# discarded. -CREATE_BIG_OBJECT_FILE = ( \ - cd $(BUILD_DIR_WANBOOT); \ - $(LD) -o wanboot-openssl.o -r -M../../mapfile.wanboot -Breduce \ - -zdiscard-unused=sections,files -zguidance \ - $(WANBOOT_OBJS); \ - ) - -$(BUILD_DIR_WANBOOT)/.built: COMPONENT_POST_BUILD_ACTION = \ - ($(CREATE_BIG_OBJECT_FILE); ) - -# OpenSSL uses sections man[1357] by default so we must create the man -# directories we use for OpenSSL man pages in Solaris. Note that we patch the -# OpenSSL man page install script to use the correct directories. -MANDIR_SECTIONS = $(PROTO_DIR)/usr/share/man/man1openssl -MANDIR_SECTIONS += $(PROTO_DIR)/usr/share/man/man3openssl -MANDIR_SECTIONS += $(PROTO_DIR)/usr/share/man/man5openssl -MANDIR_SECTIONS += $(PROTO_DIR)/usr/share/man/man7openssl - -# We must create man page directories manually since we patched OpenSSL install -# code to install into manXopenssl instead of manX. Also, OpenSSL does not -# install into /$(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) $(MANDIR_SECTIONS); \ - $(MKDIR) $(PROTO_DIR)/usr/lib/$(MACH64); ) - -# The install_docs target will install man pages into $(PROTO_DIR)/$(MANDIR). We -# also add /usr/perl5/bin to PATH so that OpenSSL install code can locate the -# system pod2man. If not set, OpenSSL make would use an internal implementation -# from the tarball which would corrupt some man pages. -COMPONENT_INSTALL_ARGS += PATH=$(PATH) MANDIR=/usr/share/man - -WANBOOT_TO = $(PROTO_DIR)/lib/openssl/wanboot/$(MACH64) - -# We could run OpenSSL install code for 32 bits only to process header files and -# manual pages. However, lint libraries depend on install stamps so we run -# install for 64 bit as well. Note that we must take built binary files from -# build directories, not from the proto area which contains whatever was -# installed first. -# OpenSSL for wanboot is built on sparc only. -ifeq ($(MACH), sparc) -install: $(INSTALL_32_and_64) $(BUILD_DIR_WANBOOT)/.built - $(MKDIR) -p $(WANBOOT_TO); - $(CP) $(BUILD_DIR_WANBOOT)/wanboot-openssl.o $(WANBOOT_TO); -else -install: $(INSTALL_32_and_64) -endif - -# 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) -lsoftcrypto -LFLAGS_64 := -I$(BUILD_DIR_64)/include $(LINT_FLAGS) -lsoftcrypto - -# 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) - -# There are also separate STC test suites 'openssl' and 'openssl-engine' -# for regression testing. These internal tests are unit tests only. -COMPONENT_TEST_TARGETS = test -test: $(TEST_32_and_64) - -system-test: $(SYSTEM_TESTS_NOT_IMPLEMENTED) - - -REQUIRED_PACKAGES += developer/build/makedepend -REQUIRED_PACKAGES += system/library diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11.c --- a/components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11.c Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3720 +0,0 @@ -/* - * Copyright (c) 2004, 2015, 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 - * licensing@OpenSSL.org. - * - * 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 - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef OPENSSL_NO_RSA -#include -#endif -#ifndef OPENSSL_NO_DSA -#include -#endif -#ifndef OPENSSL_NO_DH -#include -#endif -#include -#include -#include -#include -#include -#include - -#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 SOLARIS_HW_SLOT_SELECTION -#include -#endif - -#ifdef DEBUG_SLOT_SELECTION -#define DEBUG_SLOT_SEL(...) fprintf(stderr, __VA_ARGS__) -#else -#define DEBUG_SLOT_SEL(...) -#endif - -#include -#include -#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" - -/* - * 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 = NULL; - -#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, - PK11_AES_128_CTR, - PK11_AES_192_CTR, - PK11_AES_256_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); -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, size_t 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_choose_rand_slot(CK_TOKEN_INFO token_info, - CK_SLOT_ID current_slot); -static void pk11_choose_pubkey_slot(CK_MECHANISM_INFO mech_info, - CK_TOKEN_INFO token_info, CK_SLOT_ID current_slot, CK_RV rv, - int best_number_of_mechs, CK_SLOT_ID best_pubkey_slot_sofar); -static void pk11_choose_cipher_digest(int *local_cipher_nids, - int *local_digest_nids, CK_FUNCTION_LIST_PTR pflist, - CK_SLOT_ID current_slot); -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); -static int hw_aes_instruction_set_present(void); -#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, }, - { PK11_AES_128_CTR, NID_aes_128_ctr, 16, 16, 16, - CKK_AES, CKM_AES_CTR, }, - { PK11_AES_192_CTR, NID_aes_192_ctr, 16, 24, 24, - CKK_AES, CKM_AES_CTR, }, - { PK11_AES_256_CTR, NID_aes_256_ctr, 16, 32, 32, - CKK_AES, CKM_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 - }; - -static EVP_CIPHER pk11_aes_128_ctr = - { - NID_aes_128_ctr, - 16, 16, 16, - EVP_CIPH_CTR_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_aes_192_ctr, - 16, 24, 16, - EVP_CIPH_CTR_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_aes_256_ctr, - 16, 32, 16, - EVP_CIPH_CTR_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_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, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, - 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, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, - 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, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, - 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, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, - 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, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, - 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 ENGINE* pk11_engine = NULL; - -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; - } - } - /* Free uri_lock */ - (void) pthread_mutex_destroy(uri_lock); - OPENSSL_free(uri_lock); - uri_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); - - if (!ENGINE_set_pkey_meths(e, pk11_engine_pkey_methods)) - 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; - - /* invalidate the global session */ - global_session = CK_INVALID_HANDLE; - - 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)); - } - -/* - * Helper function that unsets reference to current engine (pk11_engine = NULL). - * - * Use of local variable only seems clumsy, it needs to be this way! - * This is to prevent double free in the unlucky scenario: - * ENGINE_free calls pk11_destroy calls pk11_finish calls ENGINE_free - * Setting pk11_engine to NULL prior to ENGINE_free() avoids this. - */ -static void pk11_engine_free() - { - ENGINE* old_engine = pk11_engine; - - if (old_engine) - { - pk11_engine = NULL; - } - } - -/* - * 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; - - if (e != pk11_engine) - { - pk11_engine_free(); - pk11_engine = e; - } - - /* - * 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 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; - - /* Attempt to load PKCS#11 library. */ - if (!pk11_dso) - { - pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0); - if (pk11_dso == NULL) - { - PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE); - goto err; - } - } - -#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 (!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) - { - int rtn = 1; - - free_PK11_LIBNAME(); - ERR_unload_pk11_strings(); - if (pk11_library_initialized == CK_TRUE) - rtn = pk11_finish(e); - - return (rtn); - } - -/* - * Termination function to clean up the session, the token, and the pk11 - * library. - */ -/* ARGSUSED */ -static int pk11_finish(ENGINE *e) - { - int i; - - /* - * Make sure, right engine instance is being destroyed. - * Engine e may be the wrong instance if - * 1) either someone calls ENGINE_load_pk11 twice - * 2) or last ref. to an already finished engine is being destroyed - */ - if (e != pk11_engine) - goto err; - - 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); - - /* Global session is not present when there are no slots. */ - if (global_session != CK_INVALID_HANDLE) - { - 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 - 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; - pk11_engine_free(); - /* - * 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; - } - } - 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; - CK_AES_CTR_PARAMS ctr_params; - - /* - * 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); - - 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 - { - 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, size_t 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_aes_128_ctr: - *cipher = &pk11_aes_128_ctr; - break; - case NID_aes_192_ctr: - *cipher = &pk11_aes_192_ctr; - break; - case NID_aes_256_ctr: - *cipher = &pk11_aes_256_ctr; - break; - case NID_bf_cbc: - *cipher = &pk11_bf_cbc; - break; - case NID_rc4: - *cipher = &pk11_rc4; - break; - default: - *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; - /* - * A special case. For "openssl dgst -dss1 -engine pkcs11 ...", - * OpenSSL calls EVP_get_digestbyname() on "dss1" which ends up - * calling pk11_engine_digests() for NID_dsa. Internally, if an - * engine is not used, OpenSSL uses SHA1_Init() as expected for - * DSA. So, we must return pk11_sha1() for NID_dsa as well. Note - * that this must have changed between 0.9.8 and 1.0.0 since we - * did not have the problem with the 0.9.8 version. - */ - case NID_sha1: - case NID_dsa: - *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; - - if (from->md_data == NULL || to->digest->ctx_size == 0) - return (1); - - /* The copy-from state */ - state = (PK11_CIPHER_STATE *) from->md_data; - if (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_pubkey_slot_sofar; - CK_SLOT_ID current_slot = 0; - int best_number_of_mechs = 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); - - pubkey_SLOTID = pSlotList[0]; - for (i = 0; i < ulSlotCount; i++) - { - current_slot = pSlotList[i]; - DEBUG_SLOT_SEL("%s: == checking slot: %d ==\n", PK11_DBG, - current_slot); - 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); - - pk11_choose_rand_slot(token_info, current_slot); - - pk11_choose_pubkey_slot(mech_info, token_info, current_slot, - rv, best_number_of_mechs, best_pubkey_slot_sofar); - - (void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids)); - (void) memset(local_digest_nids, 0, sizeof (local_digest_nids)); - pk11_choose_cipher_digest(local_cipher_nids, - local_digest_nids, pFuncList, current_slot); - } - - if (best_number_of_mechs == 0) - { - DEBUG_SLOT_SEL("%s: no rsa/dsa/dh\n", PK11_DBG); - } - else - { - pubkey_SLOTID = best_pubkey_slot_sofar; - } - - 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_choose_rand_slot(CK_TOKEN_INFO token_info, - CK_SLOT_ID current_slot) - { - DEBUG_SLOT_SEL("%s: checking rand slots\n", PK11_DBG); - if (((token_info.flags & CKF_RNG) != 0) && !pk11_have_random) - { - DEBUG_SLOT_SEL("%s: this token has CKF_RNG flag\n", PK11_DBG); - pk11_have_random = CK_TRUE; - rand_SLOTID = current_slot; - } - } - -static void pk11_choose_pubkey_slot(CK_MECHANISM_INFO mech_info, - CK_TOKEN_INFO token_info, CK_SLOT_ID current_slot, CK_RV rv, - int best_number_of_mechs, CK_SLOT_ID best_pubkey_slot_sofar) - { - CK_BBOOL slot_has_rsa = CK_FALSE; - CK_BBOOL slot_has_dsa = CK_FALSE; - CK_BBOOL slot_has_dh = CK_FALSE; - int current_number_of_mechs = 0; - - DEBUG_SLOT_SEL("%s: checking pubkey slots\n", PK11_DBG); - -#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; - current_number_of_mechs++; - } - } -#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; - current_number_of_mechs++; - } -#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; - current_number_of_mechs++; - } - } -#endif /* OPENSSL_NO_DH */ - - if (current_number_of_mechs > best_number_of_mechs) - { - best_pubkey_slot_sofar = current_slot; - pk11_have_rsa = slot_has_rsa; - pk11_have_dsa = slot_has_dsa; - pk11_have_dh = slot_has_dh; - best_number_of_mechs = current_number_of_mechs; - /* - * 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: pubkey flags changed to " - "%lu.\n", PK11_DBG, pubkey_token_flags); - } - } - -static void pk11_choose_cipher_digest(int *local_cipher_nids, - int *local_digest_nids, CK_FUNCTION_LIST_PTR pflist, - CK_SLOT_ID current_slot) - { - int current_slot_n_cipher = 0; - int current_slot_n_digest = 0; - - DEBUG_SLOT_SEL("%s: checking cipher/digest\n", PK11_DBG); - - pk11_find_symmetric_ciphers(pFuncList, current_slot, - ¤t_slot_n_cipher, local_cipher_nids); - - pk11_find_digests(pFuncList, current_slot, - ¤t_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); - /* - * 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) > - (cipher_count + digest_count)) - { - DEBUG_SLOT_SEL("%s: changing best slot to %d\n", - PK11_DBG, current_slot); - SLOTID = current_slot; - cipher_count = current_slot_n_cipher; - digest_count = current_slot_n_digest; - OPENSSL_assert(cipher_count <= PK11_CIPHER_MAX); - OPENSSL_assert(digest_count <= PK11_DIGEST_MAX); - (void) memcpy(cipher_nids, local_cipher_nids, - sizeof (int) * cipher_count); - (void) memcpy(digest_nids, local_digest_nids, - sizeof (int) * digest_count); - } - } - -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) - { - static CK_MECHANISM_INFO mech_info; - static CK_RV rv; - static CK_MECHANISM_TYPE last_checked_mech = (CK_MECHANISM_TYPE)-1; - - OPENSSL_assert(cipher->mech_type != (CK_MECHANISM_TYPE)-1); - - DEBUG_SLOT_SEL("%s: checking mech: %x", PK11_DBG, cipher->mech_type); - if (cipher->mech_type != last_checked_mech) - { - rv = pflist->C_GetMechanismInfo(slot_id, cipher->mech_type, - &mech_info); - } - - last_checked_mech = cipher->mech_type; - - 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; - } - -/* 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 unless the mechanism is - * supported directly in a CPU instruction set. The table may be NULL (i.e., - * non-existent). - */ -static int nid_in_table(int nid, int *nid_table) - { - int i = 0; - - /* - * Special case first. NULL means that we are initializing a new table. - */ - if (nid_table == NULL) - return (1); - -#if defined(__x86) - /* - * On Intel, if we have AES-NI instruction set we route AES to the - * Crypto Framework. Intel CPUs do not have other instruction sets for - * HW crypto acceleration so we check the HW NID table for any other - * mechanism. - */ - if (hw_aes_instruction_set_present() == 1) - { - switch (nid) - { - case NID_aes_128_ecb: - case NID_aes_192_ecb: - case NID_aes_256_ecb: - case NID_aes_128_cbc: - case NID_aes_192_cbc: - case NID_aes_256_cbc: - case NID_aes_128_ctr: - case NID_aes_192_ctr: - case NID_aes_256_ctr: - return (1); - } - } -#elif defined(__sparc) - if (hw_aes_instruction_set_present() == 1) - return (1); -#endif - - /* 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); - } - -/* Do we have an AES instruction set? */ -static int -hw_aes_instruction_set_present(void) - { - static int present = -1; - - if (present == -1) - { - uint_t ui = 0; - - (void) getisax(&ui, 1); - -#if defined(__amd64) || defined(__i386) - present = (ui & AV_386_AES) > 0; -#elif defined(__sparc) - present = (ui & (AV_SPARC_AES|AV_SPARC_FJAES)) > 0; -#endif - } - - return (present); - } - -#endif /* SOLARIS_HW_SLOT_SELECTION */ - -#endif /* OPENSSL_NO_HW_PK11 */ -#endif /* OPENSSL_NO_HW */ diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11.h --- a/components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11.h Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2004, 2013, 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 - * licensing@OpenSSL.org. - * - * 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 - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef E_PK11_H -#define E_PK11_H - -#include "e_pk11_err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* max byte length of a symmetric 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 split 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 int pk11_engine_pkey_methods(ENGINE *e, EVP_PKEY_METHOD **pmeth, - const int **nids, int nid); - -extern CK_FUNCTION_LIST_PTR pFuncList; - -#ifdef __cplusplus -} -#endif -#endif /* E_PK11_H */ diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_err.c --- a/components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_err.c Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,306 +0,0 @@ -/* - * Copyright (c) 2004, 2013, 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 - * licensing@OpenSSL.org. - * - * 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 - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#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); - } diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_err.h --- a/components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_err.h Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,242 +0,0 @@ -/* - * Copyright (c) 2004, 2013, 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 - * licensing@OpenSSL.org. - * - * 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 - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef E_PK11_ERR_H -#define E_PK11_ERR_H - -#ifdef __cplusplus -extern "C" { -#endif - -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 - -#ifdef __cplusplus -} -#endif -#endif /* E_PK11_ERR_H */ diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_pub.c --- a/components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_pub.c Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3273 +0,0 @@ -/* - * Copyright (c) 2004, 2013, 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 - * licensing@OpenSSL.org. - * - * 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 - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#ifndef OPENSSL_NO_RSA -#include -#endif /* OPENSSL_NO_RSA */ -#ifndef OPENSSL_NO_DSA -#include -#endif /* OPENSSL_NO_DSA */ -#ifndef OPENSSL_NO_DH -#include -#endif /* OPENSSL_NO_DH */ -#include -#include -#include -#include -#include - -#ifndef OPENSSL_NO_HW -#ifndef OPENSSL_NO_HW_PK11 - -#include -#include -#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, const 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); - -static int pk11_pkey_meth_nids[] = {NID_dsa}; - -/* 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 */ - /* Internal rsa_keygen will be used if this is NULL. */ - NULL /* rsa_keygen */ - }; - -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 -/* - * Similar 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 caught 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 = ¶meter; - - 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, const 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 = ¶meter; - 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, - (CK_BYTE_PTR)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); - } - -/* - * OpenSSL 1.0.0 introduced ENGINE API for the PKEY EVP functions. Sadly, - * "openssl dgst -dss1 ..." now uses a new function EVP_DigestSignInit() which - * internally needs a PKEY method for DSA even when in the engine. So, to avoid - * a regression when moving from 0.9.8 to 1.0.0, we use an internal OpenSSL - * structure for the DSA PKEY methods to make it work. It is a future project to - * make it work with HW acceleration. - * - * Note that at the time of 1.0.0d release there is no documentation as to how - * the PKEY EVP functions are to be implemented in an engine. There is only one - * engine shipped with 1.0.0d that uses the PKEY EVP methods, the GOST engine. - * It was used as an example when fixing the above mentioned regression problem. - */ -int -pk11_engine_pkey_methods(ENGINE *e, EVP_PKEY_METHOD **pmeth, const int **nids, - int nid) - { - if (pmeth == NULL) - { - *nids = pk11_pkey_meth_nids; - return (1); - } - - switch (nid) - { - case NID_dsa: - *pmeth = (EVP_PKEY_METHOD *)EVP_PKEY_meth_find(nid); - return (1); - } - - /* Error branch. */ - *pmeth = NULL; - return (0); - } - -#endif /* OPENSSL_NO_HW_PK11 */ -#endif /* OPENSSL_NO_HW */ diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_uri.c --- a/components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_uri.c Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,887 +0,0 @@ -/* - * Copyright (c) 2010, 2015, 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 - * licensing@OpenSSL.org. - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifndef OPENSSL_NO_HW -#ifndef OPENSSL_NO_HW_PK11 - -#include -#include -#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 */ diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_uri.h --- a/components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_uri.h Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2004, 2013, 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 - * licensing@OpenSSL.org. - * - * 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 - -#ifdef __cplusplus -extern "C" { -#endif - -/* 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); - -#ifdef __cplusplus -} -#endif -#endif /* E_PK11_URI_H */ diff -r 54dafbe33fdb -r 1fb8a14c6702 components/openssl/openssl-1.0.1/files/openssl.5 --- a/components/openssl/openssl-1.0.1/files/openssl.5 Fri Aug 28 07:46:44 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,208 +0,0 @@ -'\" te -.\" Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. -.TH openssl 5 "22 May 2015" "SunOS 5.12" "Standards, Environments, and Macros" -.SH NAME -openssl \- OpenSSL cryptographic and Secure Sockets Layer toolkit -.SH DESCRIPTION -.sp -.LP -OpenSSL is a cryptography toolkit that implements the Transport Layer Security (TLS v1) network protocols. This version of OpenSSL no longer supports the Secure Sockets Layer (SSLv2/v3) network protocols. -.sp -.LP -The following features are omitted from the binaries for issues including but not limited to patents, trademark, and US export restrictions: ECC, IDEA, MDC2, RC3, RC5, 4758_CCA Engine, AEP Engine, Atalla Engine, CHIL Engine, CSWIFT Engine, GMP Engine, NURON Engine, PadLock Engine, Sureware Engine, and UBSEC Engine. -.SS "The Dynamic Engine Support" -.sp -.LP -The dynamic engine support has been enabled, which allows an external engine, in the form of a shared library, to be dynamically bound and used by an OpenSSL-based application. -.sp -.LP -Run the following command to see if the dynamic engine is supported: -.sp -.in +2 -.nf -$ \fBopenssl engine dynamic\fR -(dynamic) Dynamic engine loading support -.fi -.in -2 -.sp - -.SS "The PKCS#11 Engine" -.sp -.LP -The PKCS#11 engine has been included with ENGINE name \fBpkcs11\fR. The engine was developed in Sun and is not integrated in the OpenSSL project. -.sp -.LP -The PKCS#11 engine is a dynamic engine, and it is configured to use the Oracle Solaris Cryptographic Framework. See \fBcryptoadm\fR(1M) for configuration information. -.sp -.LP -The PKCS#11 engine can support the following set of mechanisms: \fBCKM_AES_CBC\fR, \fBCKM_AES_ECB\fR, \fBCKM_BLOWFISH_CBC\fR, \fBCKM_DES_CBC\fR, \fBCKM_DES_ECB\fR, \fBCKM_DES3_CBC\fR, \fBCKM_DES3_ECB\fR, \fBCKM_DSA\fR, \fBCKM_MD5\fR, \fBCKM_RC4\fR, \fBCKM_RSA_PKCS\fR, \fBCKM_RSA_X_509\fR, \fBCKM_SHA_1\fR, \fBCKM_SHA224\fR, \fBCKM_SHA256\fR, \fBCKM_SHA384\fR, \fBCKM_SHA512\fR, \fBCKM_SHA224_HMAC\fR, \fBCKM_SHA224_HMAC_GENERAL\fR, and \fBCKM_SHA224_KEY_DERIVATION\fR. -.sp -.LP -The set of mechanisms available depends on installed Crypto Framework providers. To see what mechanisms can be offloaded to the Cryptographic Framework through the PKCS#11 engine on a given machine, run the following command: -.sp -.in +2 -.nf -$ \fB/usr/bin/openssl engine dynamic -pre SO_PATH:/lib/openssl/engines/64/libpk11.so -pre LOAD -t -c\fR -.fi -.in -2 -.sp - -.sp -.LP -In order to verify the use of the PKCS#11 engine and the use of hardware acceleration with the OpenSSL application, you must specify the EVP option. EVP stands for \fBEnVeloPE\fR API, which is the API applications such as Apache use to access OpenSSL cryptography. Use the EVP option to get the most accurate \fBopenssl speed\fR results. -.sp -.in +2 -.nf -$ \fB/usr/bin/openssl speed -evp aes-128-cbc -engine pkcs11\fR -.fi -.in -2 -.sp - -.sp -.LP -Due to requirements of the PKCS#11 standard regarding \fBfork\fR(2) behavior, some applications that use the OpenSSL EVP interfaces and \fBfork()\fR with active \fBcrypto\fR contexts might experience unexpected behavior. -.SS "Using FIPS Mode" -.sp -.LP -FIPS-140 capable OpenSSL is available in Oracle Solaris. -.sp -.LP -The IPS package mediator feature is used to activate the non-FIPS-140 version or the FIPS-140 version of OpenSSL. -.sp -.LP -By default, the non-FIPS-140 version (\fBdefault\fR implementation) is activated. Use the \fBpkg set-mediator\fR command to switch to the FIPS-140 version of OpenSSL: -.sp -.in +2 -.nf -# \fBpkg set-mediator -I fips-140 openssl\fR -.fi -.in -2 -.sp - -.sp -.LP -To switch back to the default non-FIPS-140 version, use the following command: -.sp -.in +2 -.nf -# \fBpkg set-mediator -I default openssl\fR -.fi -.in -2 -.sp - -.sp -.LP -Reboot is required to enforce the change system-wide. -.sp -.LP -See \fIManaging Encryption and Certificates in Oracle Solaris 11.2\fR for more details. -.sp -.LP -When the FIPS-140 version of OpenSSL is activated, an application can run in FIPS-140 mode or non-FIPS-140 mode. An application must explicitly call \fBFIPS_mode_set()\fR in order to activate FIPS-140 mode. -.SS "Building an OpenSSL Application" -.sp -.LP -To build an OpenSSL application, use the following \fBcc\fR command line options: -.sp -.in +2 -.nf -cc [ \fIflag\fR... ] \fIfile\fR... -lcrypto -lssl [ \fIlibrary\fR... ] -.fi -.in -2 - -.SS "Accessing RSA Keys in PKCS#11 Keystores" -.sp -.LP -OpenSSL can access RSA keys in PKCS#11 keystores using the following functions of the ENGINE API: -.sp -.in +2 -.nf -EVP_PKEY *ENGINE_load_private_key(ENGINE *e, - const char *key_id, UI_METHOD *ui_method, - void *callback_data) - -EVP_PKEY *ENGINE_load_public_key(ENGINE *e, - const char *key_id, UI_METHOD *ui_method, - void *callback_data) -.fi -.in -2 - -.sp -.LP -\fBkey_id\fR, formerly for filenames only, can be now also set to a \fBPKCS#11 URI\fR. The \fBEVP_PKEY\fR structure is newly allocated and caller is responsible to free the structure later. To avoid clashes with existing filenames, \fBfile://\fR prefix for filenames is now also accepted but only when the PKCS#11 engine is in use. The PKCS#11 URI specification follows: -.sp -.in +2 -.nf -pkcs11:[token=