LCOV - code coverage report
Current view: top level - home/mbr/git/openssl.git/engines - e_chil.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 61 448 13.6 %
Date: 2014-08-02 Functions: 7 28 25.0 %
Branches: 20 259 7.7 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/engine/e_chil.c -*- mode: C; c-file-style: "eay" -*- */
       2                 :            : /* Written by Richard Levitte (richard@levitte.org), Geoff Thorpe
       3                 :            :  * (geoff@geoffthorpe.net) and Dr Stephen N Henson (steve@openssl.org)
       4                 :            :  * for the OpenSSL project 2000.
       5                 :            :  */
       6                 :            : /* ====================================================================
       7                 :            :  * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
       8                 :            :  *
       9                 :            :  * Redistribution and use in source and binary forms, with or without
      10                 :            :  * modification, are permitted provided that the following conditions
      11                 :            :  * are met:
      12                 :            :  *
      13                 :            :  * 1. Redistributions of source code must retain the above copyright
      14                 :            :  *    notice, this list of conditions and the following disclaimer. 
      15                 :            :  *
      16                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      17                 :            :  *    notice, this list of conditions and the following disclaimer in
      18                 :            :  *    the documentation and/or other materials provided with the
      19                 :            :  *    distribution.
      20                 :            :  *
      21                 :            :  * 3. All advertising materials mentioning features or use of this
      22                 :            :  *    software must display the following acknowledgment:
      23                 :            :  *    "This product includes software developed by the OpenSSL Project
      24                 :            :  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
      25                 :            :  *
      26                 :            :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      27                 :            :  *    endorse or promote products derived from this software without
      28                 :            :  *    prior written permission. For written permission, please contact
      29                 :            :  *    licensing@OpenSSL.org.
      30                 :            :  *
      31                 :            :  * 5. Products derived from this software may not be called "OpenSSL"
      32                 :            :  *    nor may "OpenSSL" appear in their names without prior written
      33                 :            :  *    permission of the OpenSSL Project.
      34                 :            :  *
      35                 :            :  * 6. Redistributions of any form whatsoever must retain the following
      36                 :            :  *    acknowledgment:
      37                 :            :  *    "This product includes software developed by the OpenSSL Project
      38                 :            :  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
      39                 :            :  *
      40                 :            :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      41                 :            :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      42                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      43                 :            :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      44                 :            :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      45                 :            :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      46                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      47                 :            :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      49                 :            :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      50                 :            :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      51                 :            :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      52                 :            :  * ====================================================================
      53                 :            :  *
      54                 :            :  * This product includes cryptographic software written by Eric Young
      55                 :            :  * (eay@cryptsoft.com).  This product includes software written by Tim
      56                 :            :  * Hudson (tjh@cryptsoft.com).
      57                 :            :  *
      58                 :            :  */
      59                 :            : 
      60                 :            : #include <stdio.h>
      61                 :            : #include <string.h>
      62                 :            : #include <openssl/crypto.h>
      63                 :            : #include <openssl/pem.h>
      64                 :            : #include <openssl/dso.h>
      65                 :            : #include <openssl/engine.h>
      66                 :            : #include <openssl/ui.h>
      67                 :            : #include <openssl/rand.h>
      68                 :            : #ifndef OPENSSL_NO_RSA
      69                 :            : #include <openssl/rsa.h>
      70                 :            : #endif
      71                 :            : #ifndef OPENSSL_NO_DH
      72                 :            : #include <openssl/dh.h>
      73                 :            : #endif
      74                 :            : #include <openssl/bn.h>
      75                 :            : 
      76                 :            : #ifndef OPENSSL_NO_HW
      77                 :            : #ifndef OPENSSL_NO_HW_CHIL
      78                 :            : 
      79                 :            : /* Attribution notice: nCipher have said several times that it's OK for
      80                 :            :  * us to implement a general interface to their boxes, and recently declared
      81                 :            :  * their HWCryptoHook to be public, and therefore available for us to use.
      82                 :            :  * Thanks, nCipher.
      83                 :            :  *
      84                 :            :  * The hwcryptohook.h included here is from May 2000.
      85                 :            :  * [Richard Levitte]
      86                 :            :  */
      87                 :            : #ifdef FLAT_INC
      88                 :            : #include "hwcryptohook.h"
      89                 :            : #else
      90                 :            : #include "vendor_defns/hwcryptohook.h"
      91                 :            : #endif
      92                 :            : 
      93                 :            : #define HWCRHK_LIB_NAME "CHIL engine"
      94                 :            : #include "e_chil_err.c"
      95                 :            : 
      96                 :            : static int hwcrhk_destroy(ENGINE *e);
      97                 :            : static int hwcrhk_init(ENGINE *e);
      98                 :            : static int hwcrhk_finish(ENGINE *e);
      99                 :            : static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); 
     100                 :            : 
     101                 :            : /* Functions to handle mutexes */
     102                 :            : static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*);
     103                 :            : static int hwcrhk_mutex_lock(HWCryptoHook_Mutex*);
     104                 :            : static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*);
     105                 :            : static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*);
     106                 :            : 
     107                 :            : /* BIGNUM stuff */
     108                 :            : static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
     109                 :            :                 const BIGNUM *m, BN_CTX *ctx);
     110                 :            : 
     111                 :            : #ifndef OPENSSL_NO_RSA
     112                 :            : /* RSA stuff */
     113                 :            : static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
     114                 :            : /* This function is aliased to mod_exp (with the mont stuff dropped). */
     115                 :            : static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
     116                 :            :                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
     117                 :            : static int hwcrhk_rsa_finish(RSA *rsa);
     118                 :            : #endif
     119                 :            : 
     120                 :            : #ifndef OPENSSL_NO_DH
     121                 :            : /* DH stuff */
     122                 :            : /* This function is alised to mod_exp (with the DH and mont dropped). */
     123                 :            : static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
     124                 :            :         const BIGNUM *a, const BIGNUM *p,
     125                 :            :         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
     126                 :            : #endif
     127                 :            : 
     128                 :            : /* RAND stuff */
     129                 :            : static int hwcrhk_rand_bytes(unsigned char *buf, int num);
     130                 :            : static int hwcrhk_rand_status(void);
     131                 :            : 
     132                 :            : /* KM stuff */
     133                 :            : static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
     134                 :            :         UI_METHOD *ui_method, void *callback_data);
     135                 :            : static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
     136                 :            :         UI_METHOD *ui_method, void *callback_data);
     137                 :            : 
     138                 :            : /* Interaction stuff */
     139                 :            : static int hwcrhk_insert_card(const char *prompt_info,
     140                 :            :         const char *wrong_info,
     141                 :            :         HWCryptoHook_PassphraseContext *ppctx,
     142                 :            :         HWCryptoHook_CallerContext *cactx);
     143                 :            : static int hwcrhk_get_pass(const char *prompt_info,
     144                 :            :         int *len_io, char *buf,
     145                 :            :         HWCryptoHook_PassphraseContext *ppctx,
     146                 :            :         HWCryptoHook_CallerContext *cactx);
     147                 :            : static void hwcrhk_log_message(void *logstr, const char *message);
     148                 :            : 
     149                 :            : /* The definitions for control commands specific to this engine */
     150                 :            : #define HWCRHK_CMD_SO_PATH              ENGINE_CMD_BASE
     151                 :            : #define HWCRHK_CMD_FORK_CHECK           (ENGINE_CMD_BASE + 1)
     152                 :            : #define HWCRHK_CMD_THREAD_LOCKING       (ENGINE_CMD_BASE + 2)
     153                 :            : #define HWCRHK_CMD_SET_USER_INTERFACE   (ENGINE_CMD_BASE + 3)
     154                 :            : #define HWCRHK_CMD_SET_CALLBACK_DATA    (ENGINE_CMD_BASE + 4)
     155                 :            : static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = {
     156                 :            :         {HWCRHK_CMD_SO_PATH,
     157                 :            :                 "SO_PATH",
     158                 :            :                 "Specifies the path to the 'hwcrhk' shared library",
     159                 :            :                 ENGINE_CMD_FLAG_STRING},
     160                 :            :         {HWCRHK_CMD_FORK_CHECK,
     161                 :            :                 "FORK_CHECK",
     162                 :            :                 "Turns fork() checking on (non-zero) or off (zero)",
     163                 :            :                 ENGINE_CMD_FLAG_NUMERIC},
     164                 :            :         {HWCRHK_CMD_THREAD_LOCKING,
     165                 :            :                 "THREAD_LOCKING",
     166                 :            :                 "Turns thread-safe locking on (zero) or off (non-zero)",
     167                 :            :                 ENGINE_CMD_FLAG_NUMERIC},
     168                 :            :         {HWCRHK_CMD_SET_USER_INTERFACE,
     169                 :            :                 "SET_USER_INTERFACE",
     170                 :            :                 "Set the global user interface (internal)",
     171                 :            :                 ENGINE_CMD_FLAG_INTERNAL},
     172                 :            :         {HWCRHK_CMD_SET_CALLBACK_DATA,
     173                 :            :                 "SET_CALLBACK_DATA",
     174                 :            :                 "Set the global user interface extra data (internal)",
     175                 :            :                 ENGINE_CMD_FLAG_INTERNAL},
     176                 :            :         {0, NULL, NULL, 0}
     177                 :            :         };
     178                 :            : 
     179                 :            : #ifndef OPENSSL_NO_RSA
     180                 :            : /* Our internal RSA_METHOD that we provide pointers to */
     181                 :            : static RSA_METHOD hwcrhk_rsa =
     182                 :            :         {
     183                 :            :         "CHIL RSA method",
     184                 :            :         NULL,
     185                 :            :         NULL,
     186                 :            :         NULL,
     187                 :            :         NULL,
     188                 :            :         hwcrhk_rsa_mod_exp,
     189                 :            :         hwcrhk_mod_exp_mont,
     190                 :            :         NULL,
     191                 :            :         hwcrhk_rsa_finish,
     192                 :            :         0,
     193                 :            :         NULL,
     194                 :            :         NULL,
     195                 :            :         NULL,
     196                 :            :         NULL
     197                 :            :         };
     198                 :            : #endif
     199                 :            : 
     200                 :            : #ifndef OPENSSL_NO_DH
     201                 :            : /* Our internal DH_METHOD that we provide pointers to */
     202                 :            : static DH_METHOD hwcrhk_dh =
     203                 :            :         {
     204                 :            :         "CHIL DH method",
     205                 :            :         NULL,
     206                 :            :         NULL,
     207                 :            :         hwcrhk_mod_exp_dh,
     208                 :            :         NULL,
     209                 :            :         NULL,
     210                 :            :         0,
     211                 :            :         NULL,
     212                 :            :         NULL
     213                 :            :         };
     214                 :            : #endif
     215                 :            : 
     216                 :            : static RAND_METHOD hwcrhk_rand =
     217                 :            :         {
     218                 :            :         /* "CHIL RAND method", */
     219                 :            :         NULL,
     220                 :            :         hwcrhk_rand_bytes,
     221                 :            :         NULL,
     222                 :            :         NULL,
     223                 :            :         hwcrhk_rand_bytes,
     224                 :            :         hwcrhk_rand_status,
     225                 :            :         };
     226                 :            : 
     227                 :            : /* Constants used when creating the ENGINE */
     228                 :            : static const char *engine_hwcrhk_id = "chil";
     229                 :            : static const char *engine_hwcrhk_name = "CHIL hardware engine support";
     230                 :            : #ifndef OPENSSL_NO_DYNAMIC_ENGINE 
     231                 :            : /* Compatibility hack, the dynamic library uses this form in the path */
     232                 :            : static const char *engine_hwcrhk_id_alt = "ncipher";
     233                 :            : #endif
     234                 :            : 
     235                 :            : /* Internal stuff for HWCryptoHook */
     236                 :            : 
     237                 :            : /* Some structures needed for proper use of thread locks */
     238                 :            : /* hwcryptohook.h has some typedefs that turn struct HWCryptoHook_MutexValue
     239                 :            :    into HWCryptoHook_Mutex */
     240                 :            : struct HWCryptoHook_MutexValue
     241                 :            :         {
     242                 :            :         int lockid;
     243                 :            :         };
     244                 :            : 
     245                 :            : /* hwcryptohook.h has some typedefs that turn
     246                 :            :    struct HWCryptoHook_PassphraseContextValue
     247                 :            :    into HWCryptoHook_PassphraseContext */
     248                 :            : struct HWCryptoHook_PassphraseContextValue
     249                 :            :         {
     250                 :            :         UI_METHOD *ui_method;
     251                 :            :         void *callback_data;
     252                 :            :         };
     253                 :            : 
     254                 :            : /* hwcryptohook.h has some typedefs that turn
     255                 :            :    struct HWCryptoHook_CallerContextValue
     256                 :            :    into HWCryptoHook_CallerContext */
     257                 :            : struct HWCryptoHook_CallerContextValue
     258                 :            :         {
     259                 :            :         pem_password_cb *password_callback; /* Deprecated!  Only present for
     260                 :            :                                                backward compatibility! */
     261                 :            :         UI_METHOD *ui_method;
     262                 :            :         void *callback_data;
     263                 :            :         };
     264                 :            : 
     265                 :            : /* The MPI structure in HWCryptoHook is pretty compatible with OpenSSL
     266                 :            :    BIGNUM's, so lets define a couple of conversion macros */
     267                 :            : #define BN2MPI(mp, bn) \
     268                 :            :     {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
     269                 :            : #define MPI2BN(bn, mp) \
     270                 :            :     {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
     271                 :            : 
     272                 :            : static BIO *logstream = NULL;
     273                 :            : static int disable_mutex_callbacks = 0;
     274                 :            : 
     275                 :            : /* One might wonder why these are needed, since one can pass down at least
     276                 :            :    a UI_METHOD and a pointer to callback data to the key-loading functions.
     277                 :            :    The thing is that the ModExp and RSAImmed functions can load keys as well,
     278                 :            :    if the data they get is in a special, nCipher-defined format (hint: if you
     279                 :            :    look at the private exponent of the RSA data as a string, you'll see this
     280                 :            :    string: "nCipher KM tool key id", followed by some bytes, followed a key
     281                 :            :    identity string, followed by more bytes.  This happens when you use "embed"
     282                 :            :    keys instead of "hwcrhk" keys).  Unfortunately, those functions do not take
     283                 :            :    any passphrase or caller context, and our functions can't really take any
     284                 :            :    callback data either.  Still, the "insert_card" and "get_passphrase"
     285                 :            :    callbacks may be called down the line, and will need to know what user
     286                 :            :    interface callbacks to call, and having callback data from the application
     287                 :            :    may be a nice thing as well, so we need to keep track of that globally. */
     288                 :            : static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL };
     289                 :            : 
     290                 :            : /* Stuff to pass to the HWCryptoHook library */
     291                 :            : static HWCryptoHook_InitInfo hwcrhk_globals = {
     292                 :            :         HWCryptoHook_InitFlags_SimpleForkCheck, /* Flags */
     293                 :            :         &logstream,         /* logstream */
     294                 :            :         sizeof(BN_ULONG),       /* limbsize */
     295                 :            :         0,                      /* mslimb first: false for BNs */
     296                 :            :         -1,                     /* msbyte first: use native */
     297                 :            :         0,                      /* Max mutexes, 0 = no small limit */
     298                 :            :         0,                      /* Max simultaneous, 0 = default */
     299                 :            : 
     300                 :            :         /* The next few are mutex stuff: we write wrapper functions
     301                 :            :            around the OS mutex functions.  We initialise them to 0
     302                 :            :            here, and change that to actual function pointers in hwcrhk_init()
     303                 :            :            if dynamic locks are supported (that is, if the application
     304                 :            :            programmer has made sure of setting up callbacks bafore starting
     305                 :            :            this engine) *and* if disable_mutex_callbacks hasn't been set by
     306                 :            :            a call to ENGINE_ctrl(ENGINE_CTRL_CHIL_NO_LOCKING). */
     307                 :            :         sizeof(HWCryptoHook_Mutex),
     308                 :            :         0,
     309                 :            :         0,
     310                 :            :         0,
     311                 :            :         0,
     312                 :            : 
     313                 :            :         /* The next few are condvar stuff: we write wrapper functions
     314                 :            :            round the OS functions.  Currently not implemented and not
     315                 :            :            and absolute necessity even in threaded programs, therefore
     316                 :            :            0'ed.  Will hopefully be implemented some day, since it
     317                 :            :            enhances the efficiency of HWCryptoHook.  */
     318                 :            :         0, /* sizeof(HWCryptoHook_CondVar), */
     319                 :            :         0, /* hwcrhk_cv_init, */
     320                 :            :         0, /* hwcrhk_cv_wait, */
     321                 :            :         0, /* hwcrhk_cv_signal, */
     322                 :            :         0, /* hwcrhk_cv_broadcast, */
     323                 :            :         0, /* hwcrhk_cv_destroy, */
     324                 :            : 
     325                 :            :         hwcrhk_get_pass,        /* pass phrase */
     326                 :            :         hwcrhk_insert_card,     /* insert a card */
     327                 :            :         hwcrhk_log_message      /* Log message */
     328                 :            : };
     329                 :            : 
     330                 :            : 
     331                 :            : /* Now, to our own code */
     332                 :            : 
     333                 :            : /* This internal function is used by ENGINE_chil() and possibly by the
     334                 :            :  * "dynamic" ENGINE support too */
     335                 :        728 : static int bind_helper(ENGINE *e)
     336                 :            :         {
     337                 :            : #ifndef OPENSSL_NO_RSA
     338                 :            :         const RSA_METHOD *meth1;
     339                 :            : #endif
     340                 :            : #ifndef OPENSSL_NO_DH
     341                 :            :         const DH_METHOD *meth2;
     342                 :            : #endif
     343   [ +  -  +  - ]:       1456 :         if(!ENGINE_set_id(e, engine_hwcrhk_id) ||
     344         [ +  - ]:       1456 :                         !ENGINE_set_name(e, engine_hwcrhk_name) ||
     345                 :            : #ifndef OPENSSL_NO_RSA
     346         [ +  - ]:       1456 :                         !ENGINE_set_RSA(e, &hwcrhk_rsa) ||
     347                 :            : #endif
     348                 :            : #ifndef OPENSSL_NO_DH
     349         [ +  - ]:       1456 :                         !ENGINE_set_DH(e, &hwcrhk_dh) ||
     350                 :            : #endif
     351         [ +  - ]:       1456 :                         !ENGINE_set_RAND(e, &hwcrhk_rand) ||
     352         [ +  - ]:       1456 :                         !ENGINE_set_destroy_function(e, hwcrhk_destroy) ||
     353         [ +  - ]:       1456 :                         !ENGINE_set_init_function(e, hwcrhk_init) ||
     354         [ +  - ]:       1456 :                         !ENGINE_set_finish_function(e, hwcrhk_finish) ||
     355         [ +  - ]:       1456 :                         !ENGINE_set_ctrl_function(e, hwcrhk_ctrl) ||
     356         [ +  - ]:       1456 :                         !ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) ||
     357         [ +  - ]:       1456 :                         !ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) ||
     358                 :        728 :                         !ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns))
     359                 :            :                 return 0;
     360                 :            : 
     361                 :            : #ifndef OPENSSL_NO_RSA
     362                 :            :         /* We know that the "PKCS1_SSLeay()" functions hook properly
     363                 :            :          * to the cswift-specific mod_exp and mod_exp_crt so we use
     364                 :            :          * those functions. NB: We don't use ENGINE_openssl() or
     365                 :            :          * anything "more generic" because something like the RSAref
     366                 :            :          * code may not hook properly, and if you own one of these
     367                 :            :          * cards then you have the right to do RSA operations on it
     368                 :            :          * anyway! */ 
     369                 :        728 :         meth1 = RSA_PKCS1_SSLeay();
     370                 :        728 :         hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
     371                 :        728 :         hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
     372                 :        728 :         hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
     373                 :        728 :         hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
     374                 :            : #endif
     375                 :            : 
     376                 :            : #ifndef OPENSSL_NO_DH
     377                 :            :         /* Much the same for Diffie-Hellman */
     378                 :        728 :         meth2 = DH_OpenSSL();
     379                 :        728 :         hwcrhk_dh.generate_key = meth2->generate_key;
     380                 :        728 :         hwcrhk_dh.compute_key = meth2->compute_key;
     381                 :            : #endif
     382                 :            : 
     383                 :            :         /* Ensure the hwcrhk error handling is set up */
     384                 :        728 :         ERR_load_HWCRHK_strings();
     385                 :        728 :         return 1;
     386                 :            :         }
     387                 :            : 
     388                 :            : #ifdef OPENSSL_NO_DYNAMIC_ENGINE
     389                 :        728 : static ENGINE *engine_chil(void)
     390                 :            :         {
     391                 :        728 :         ENGINE *ret = ENGINE_new();
     392         [ +  - ]:        728 :         if(!ret)
     393                 :            :                 return NULL;
     394         [ -  + ]:        728 :         if(!bind_helper(ret))
     395                 :            :                 {
     396                 :          0 :                 ENGINE_free(ret);
     397                 :          0 :                 return NULL;
     398                 :            :                 }
     399                 :            :         return ret;
     400                 :            :         }
     401                 :            : 
     402                 :        728 : void ENGINE_load_chil(void)
     403                 :            :         {
     404                 :            :         /* Copied from eng_[openssl|dyn].c */
     405                 :        728 :         ENGINE *toadd = engine_chil();
     406         [ +  - ]:        728 :         if(!toadd) return;
     407                 :        728 :         ENGINE_add(toadd);
     408                 :        728 :         ENGINE_free(toadd);
     409                 :        728 :         ERR_clear_error();
     410                 :            :         }
     411                 :            : #endif
     412                 :            : 
     413                 :            : /* This is a process-global DSO handle used for loading and unloading
     414                 :            :  * the HWCryptoHook library. NB: This is only set (or unset) during an
     415                 :            :  * init() or finish() call (reference counts permitting) and they're
     416                 :            :  * operating with global locks, so this should be thread-safe
     417                 :            :  * implicitly. */
     418                 :            : static DSO *hwcrhk_dso = NULL;
     419                 :            : static HWCryptoHook_ContextHandle hwcrhk_context = 0;
     420                 :            : #ifndef OPENSSL_NO_RSA
     421                 :            : static int hndidx_rsa = -1;    /* Index for KM handle.  Not really used yet. */
     422                 :            : #endif
     423                 :            : 
     424                 :            : /* These are the function pointers that are (un)set when the library has
     425                 :            :  * successfully (un)loaded. */
     426                 :            : static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL;
     427                 :            : static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL;
     428                 :            : static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL;
     429                 :            : #ifndef OPENSSL_NO_RSA
     430                 :            : static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL;
     431                 :            : #endif
     432                 :            : static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL;
     433                 :            : #ifndef OPENSSL_NO_RSA
     434                 :            : static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL;
     435                 :            : static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL;
     436                 :            : static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL;
     437                 :            : #endif
     438                 :            : static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL;
     439                 :            : 
     440                 :            : /* Used in the DSO operations. */
     441                 :            : static const char *HWCRHK_LIBNAME = NULL;
     442                 :        727 : static void free_HWCRHK_LIBNAME(void)
     443                 :            :         {
     444         [ -  + ]:        727 :         if(HWCRHK_LIBNAME)
     445                 :          0 :                 OPENSSL_free((void*)HWCRHK_LIBNAME);
     446                 :        727 :         HWCRHK_LIBNAME = NULL;
     447                 :        727 :         }
     448                 :        483 : static const char *get_HWCRHK_LIBNAME(void)
     449                 :            :         {
     450         [ -  + ]:        483 :         if(HWCRHK_LIBNAME)
     451                 :          0 :                 return HWCRHK_LIBNAME;
     452                 :            :         return "nfhwcrhk";
     453                 :            :         }
     454                 :          0 : static long set_HWCRHK_LIBNAME(const char *name)
     455                 :            :         {
     456                 :          0 :         free_HWCRHK_LIBNAME();
     457                 :          0 :         return (((HWCRHK_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
     458                 :            :         }
     459                 :            : static const char *n_hwcrhk_Init = "HWCryptoHook_Init";
     460                 :            : static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";
     461                 :            : static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";
     462                 :            : #ifndef OPENSSL_NO_RSA
     463                 :            : static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA";
     464                 :            : #endif
     465                 :            : static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes";
     466                 :            : #ifndef OPENSSL_NO_RSA
     467                 :            : static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey";
     468                 :            : static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey";
     469                 :            : static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey";
     470                 :            : #endif
     471                 :            : static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT";
     472                 :            : 
     473                 :            : /* HWCryptoHook library functions and mechanics - these are used by the
     474                 :            :  * higher-level functions further down. NB: As and where there's no
     475                 :            :  * error checking, take a look lower down where these functions are
     476                 :            :  * called, the checking and error handling is probably down there. */
     477                 :            : 
     478                 :            : /* utility function to obtain a context */
     479                 :          0 : static int get_context(HWCryptoHook_ContextHandle *hac,
     480                 :            :         HWCryptoHook_CallerContext *cac)
     481                 :            :         {
     482                 :            :         char tempbuf[1024];
     483                 :            :         HWCryptoHook_ErrMsgBuf rmsg;
     484                 :            : 
     485                 :          0 :         rmsg.buf = tempbuf;
     486                 :          0 :         rmsg.size = sizeof(tempbuf);
     487                 :            : 
     488                 :          0 :         *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg,
     489                 :            :                 cac);
     490         [ #  # ]:          0 :         if (!*hac)
     491                 :            :                 return 0;
     492                 :          0 :         return 1;
     493                 :            :         }
     494                 :            :  
     495                 :            : /* similarly to release one. */
     496                 :          0 : static void release_context(HWCryptoHook_ContextHandle hac)
     497                 :            :         {
     498                 :          0 :         p_hwcrhk_Finish(hac);
     499                 :          0 :         }
     500                 :            : 
     501                 :            : /* Destructor (complements the "ENGINE_chil()" constructor) */
     502                 :        727 : static int hwcrhk_destroy(ENGINE *e)
     503                 :            :         {
     504                 :        727 :         free_HWCRHK_LIBNAME();
     505                 :        727 :         ERR_unload_HWCRHK_strings();
     506                 :        727 :         return 1;
     507                 :            :         }
     508                 :            : 
     509                 :            : /* (de)initialisation functions. */
     510                 :        483 : static int hwcrhk_init(ENGINE *e)
     511                 :            :         {
     512                 :            :         HWCryptoHook_Init_t *p1;
     513                 :            :         HWCryptoHook_Finish_t *p2;
     514                 :            :         HWCryptoHook_ModExp_t *p3;
     515                 :            : #ifndef OPENSSL_NO_RSA
     516                 :            :         HWCryptoHook_RSA_t *p4;
     517                 :            :         HWCryptoHook_RSALoadKey_t *p5;
     518                 :            :         HWCryptoHook_RSAGetPublicKey_t *p6;
     519                 :            :         HWCryptoHook_RSAUnloadKey_t *p7;
     520                 :            : #endif
     521                 :            :         HWCryptoHook_RandomBytes_t *p8;
     522                 :            :         HWCryptoHook_ModExpCRT_t *p9;
     523                 :            : 
     524         [ -  + ]:        483 :         if(hwcrhk_dso != NULL)
     525                 :            :                 {
     526                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_ALREADY_LOADED);
     527                 :          0 :                 goto err;
     528                 :            :                 }
     529                 :            :         /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */
     530                 :        483 :         hwcrhk_dso = DSO_load(NULL, get_HWCRHK_LIBNAME(), NULL, 0);
     531         [ +  - ]:        483 :         if(hwcrhk_dso == NULL)
     532                 :            :                 {
     533                 :        483 :                 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
     534                 :        483 :                 goto err;
     535                 :            :                 }
     536         [ #  # ]:          0 :         if(!(p1 = (HWCryptoHook_Init_t *)
     537         [ #  # ]:          0 :                         DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) ||
     538                 :            :                 !(p2 = (HWCryptoHook_Finish_t *)
     539         [ #  # ]:          0 :                         DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) ||
     540                 :            :                 !(p3 = (HWCryptoHook_ModExp_t *)
     541         [ #  # ]:          0 :                         DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) ||
     542                 :            : #ifndef OPENSSL_NO_RSA
     543                 :            :                 !(p4 = (HWCryptoHook_RSA_t *)
     544         [ #  # ]:          0 :                         DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) ||
     545                 :            :                 !(p5 = (HWCryptoHook_RSALoadKey_t *)
     546         [ #  # ]:          0 :                         DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSALoadKey)) ||
     547                 :            :                 !(p6 = (HWCryptoHook_RSAGetPublicKey_t *)
     548         [ #  # ]:          0 :                         DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) ||
     549                 :            :                 !(p7 = (HWCryptoHook_RSAUnloadKey_t *)
     550         [ #  # ]:          0 :                         DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) ||
     551                 :            : #endif
     552                 :            :                 !(p8 = (HWCryptoHook_RandomBytes_t *)
     553         [ #  # ]:          0 :                         DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) ||
     554                 :            :                 !(p9 = (HWCryptoHook_ModExpCRT_t *)
     555                 :          0 :                         DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT)))
     556                 :            :                 {
     557                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
     558                 :          0 :                 goto err;
     559                 :            :                 }
     560                 :            :         /* Copy the pointers */
     561                 :          0 :         p_hwcrhk_Init = p1;
     562                 :          0 :         p_hwcrhk_Finish = p2;
     563                 :          0 :         p_hwcrhk_ModExp = p3;
     564                 :            : #ifndef OPENSSL_NO_RSA
     565                 :          0 :         p_hwcrhk_RSA = p4;
     566                 :          0 :         p_hwcrhk_RSALoadKey = p5;
     567                 :          0 :         p_hwcrhk_RSAGetPublicKey = p6;
     568                 :          0 :         p_hwcrhk_RSAUnloadKey = p7;
     569                 :            : #endif
     570                 :          0 :         p_hwcrhk_RandomBytes = p8;
     571                 :          0 :         p_hwcrhk_ModExpCRT = p9;
     572                 :            : 
     573                 :            :         /* Check if the application decided to support dynamic locks,
     574                 :            :            and if it does, use them. */
     575         [ #  # ]:          0 :         if (disable_mutex_callbacks == 0)
     576                 :            :                 {
     577   [ #  #  #  # ]:          0 :                 if (CRYPTO_get_dynlock_create_callback() != NULL &&
     578         [ #  # ]:          0 :                         CRYPTO_get_dynlock_lock_callback() != NULL &&
     579                 :          0 :                         CRYPTO_get_dynlock_destroy_callback() != NULL)
     580                 :            :                         {
     581                 :          0 :                         hwcrhk_globals.mutex_init = hwcrhk_mutex_init;
     582                 :          0 :                         hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock;
     583                 :          0 :                         hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock;
     584                 :          0 :                         hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy;
     585                 :            :                         }
     586                 :            :                 }
     587                 :            : 
     588                 :            :         /* Try and get a context - if not, we may have a DSO but no
     589                 :            :          * accelerator! */
     590         [ #  # ]:          0 :         if(!get_context(&hwcrhk_context, &password_context))
     591                 :            :                 {
     592                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_UNIT_FAILURE);
     593                 :          0 :                 goto err;
     594                 :            :                 }
     595                 :            :         /* Everything's fine. */
     596                 :            : #ifndef OPENSSL_NO_RSA
     597         [ #  # ]:          0 :         if (hndidx_rsa == -1)
     598                 :          0 :                 hndidx_rsa = RSA_get_ex_new_index(0,
     599                 :            :                         "nFast HWCryptoHook RSA key handle",
     600                 :            :                         NULL, NULL, NULL);
     601                 :            : #endif
     602                 :            :         return 1;
     603                 :            : err:
     604         [ -  + ]:        483 :         if(hwcrhk_dso)
     605                 :          0 :                 DSO_free(hwcrhk_dso);
     606                 :        483 :         hwcrhk_dso = NULL;
     607                 :        483 :         p_hwcrhk_Init = NULL;
     608                 :        483 :         p_hwcrhk_Finish = NULL;
     609                 :        483 :         p_hwcrhk_ModExp = NULL;
     610                 :            : #ifndef OPENSSL_NO_RSA
     611                 :        483 :         p_hwcrhk_RSA = NULL;
     612                 :        483 :         p_hwcrhk_RSALoadKey = NULL;
     613                 :        483 :         p_hwcrhk_RSAGetPublicKey = NULL;
     614                 :        483 :         p_hwcrhk_RSAUnloadKey = NULL;
     615                 :            : #endif
     616                 :        483 :         p_hwcrhk_ModExpCRT = NULL;
     617                 :        483 :         p_hwcrhk_RandomBytes = NULL;
     618                 :        483 :         return 0;
     619                 :            :         }
     620                 :            : 
     621                 :          0 : static int hwcrhk_finish(ENGINE *e)
     622                 :            :         {
     623                 :          0 :         int to_return = 1;
     624                 :          0 :         free_HWCRHK_LIBNAME();
     625         [ #  # ]:          0 :         if(hwcrhk_dso == NULL)
     626                 :            :                 {
     627                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_NOT_LOADED);
     628                 :          0 :                 to_return = 0;
     629                 :          0 :                 goto err;
     630                 :            :                 }
     631                 :          0 :         release_context(hwcrhk_context);
     632         [ #  # ]:          0 :         if(!DSO_free(hwcrhk_dso))
     633                 :            :                 {
     634                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_DSO_FAILURE);
     635                 :          0 :                 to_return = 0;
     636                 :          0 :                 goto err;
     637                 :            :                 }
     638                 :            :  err:
     639         [ #  # ]:          0 :         if (logstream)
     640                 :          0 :                 BIO_free(logstream);
     641                 :          0 :         hwcrhk_dso = NULL;
     642                 :          0 :         p_hwcrhk_Init = NULL;
     643                 :          0 :         p_hwcrhk_Finish = NULL;
     644                 :          0 :         p_hwcrhk_ModExp = NULL;
     645                 :            : #ifndef OPENSSL_NO_RSA
     646                 :          0 :         p_hwcrhk_RSA = NULL;
     647                 :          0 :         p_hwcrhk_RSALoadKey = NULL;
     648                 :          0 :         p_hwcrhk_RSAGetPublicKey = NULL;
     649                 :          0 :         p_hwcrhk_RSAUnloadKey = NULL;
     650                 :            : #endif
     651                 :          0 :         p_hwcrhk_ModExpCRT = NULL;
     652                 :          0 :         p_hwcrhk_RandomBytes = NULL;
     653                 :          0 :         return to_return;
     654                 :            :         }
     655                 :            : 
     656                 :          0 : static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
     657                 :            :         {
     658                 :          0 :         int to_return = 1;
     659                 :            : 
     660   [ #  #  #  #  :          0 :         switch(cmd)
             #  #  #  #  
                      # ]
     661                 :            :                 {
     662                 :            :         case HWCRHK_CMD_SO_PATH:
     663         [ #  # ]:          0 :                 if(hwcrhk_dso)
     664                 :            :                         {
     665                 :          0 :                         HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_ALREADY_LOADED);
     666                 :          0 :                         return 0;
     667                 :            :                         }
     668         [ #  # ]:          0 :                 if(p == NULL)
     669                 :            :                         {
     670                 :          0 :                         HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,ERR_R_PASSED_NULL_PARAMETER);
     671                 :          0 :                         return 0;
     672                 :            :                         }
     673                 :          0 :                 return set_HWCRHK_LIBNAME((const char *)p);
     674                 :            :         case ENGINE_CTRL_SET_LOGSTREAM:
     675                 :            :                 {
     676                 :          0 :                 BIO *bio = (BIO *)p;
     677                 :            : 
     678                 :          0 :                 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
     679         [ #  # ]:          0 :                 if (logstream)
     680                 :            :                         {
     681                 :          0 :                         BIO_free(logstream);
     682                 :          0 :                         logstream = NULL;
     683                 :            :                         }
     684         [ #  # ]:          0 :                 if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1)
     685                 :          0 :                         logstream = bio;
     686                 :            :                 else
     687                 :          0 :                         HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_BIO_WAS_FREED);
     688                 :            :                 }
     689                 :          0 :                 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
     690                 :          0 :                 break;
     691                 :            :         case ENGINE_CTRL_SET_PASSWORD_CALLBACK:
     692                 :          0 :                 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
     693                 :          0 :                 password_context.password_callback = (pem_password_cb *)f;
     694                 :          0 :                 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
     695                 :          0 :                 break;
     696                 :            :         case ENGINE_CTRL_SET_USER_INTERFACE:
     697                 :            :         case HWCRHK_CMD_SET_USER_INTERFACE:
     698                 :          0 :                 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
     699                 :          0 :                 password_context.ui_method = (UI_METHOD *)p;
     700                 :          0 :                 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
     701                 :          0 :                 break;
     702                 :            :         case ENGINE_CTRL_SET_CALLBACK_DATA:
     703                 :            :         case HWCRHK_CMD_SET_CALLBACK_DATA:
     704                 :          0 :                 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
     705                 :          0 :                 password_context.callback_data = p;
     706                 :          0 :                 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
     707                 :          0 :                 break;
     708                 :            :         /* this enables or disables the "SimpleForkCheck" flag used in the
     709                 :            :          * initialisation structure. */
     710                 :            :         case ENGINE_CTRL_CHIL_SET_FORKCHECK:
     711                 :            :         case HWCRHK_CMD_FORK_CHECK:
     712                 :          0 :                 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
     713         [ #  # ]:          0 :                 if(i)
     714                 :          0 :                         hwcrhk_globals.flags |=
     715                 :            :                                 HWCryptoHook_InitFlags_SimpleForkCheck;
     716                 :            :                 else
     717                 :          0 :                         hwcrhk_globals.flags &=
     718                 :            :                                 ~HWCryptoHook_InitFlags_SimpleForkCheck;
     719                 :          0 :                 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
     720                 :          0 :                 break;
     721                 :            :         /* This will prevent the initialisation function from "installing"
     722                 :            :          * the mutex-handling callbacks, even if they are available from
     723                 :            :          * within the library (or were provided to the library from the
     724                 :            :          * calling application). This is to remove any baggage for
     725                 :            :          * applications not using multithreading. */
     726                 :            :         case ENGINE_CTRL_CHIL_NO_LOCKING:
     727                 :          0 :                 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
     728                 :          0 :                 disable_mutex_callbacks = 1;
     729                 :          0 :                 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
     730                 :          0 :                 break;
     731                 :            :         case HWCRHK_CMD_THREAD_LOCKING:
     732                 :          0 :                 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
     733                 :          0 :                 disable_mutex_callbacks = ((i == 0) ? 0 : 1);
     734                 :          0 :                 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
     735                 :          0 :                 break;
     736                 :            : 
     737                 :            :         /* The command isn't understood by this engine */
     738                 :            :         default:
     739                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,
     740                 :            :                         HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
     741                 :          0 :                 to_return = 0;
     742                 :          0 :                 break;
     743                 :            :                 }
     744                 :            : 
     745                 :          0 :         return to_return;
     746                 :            :         }
     747                 :            : 
     748                 :          0 : static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
     749                 :            :         UI_METHOD *ui_method, void *callback_data)
     750                 :            :         {
     751                 :            : #ifndef OPENSSL_NO_RSA
     752                 :          0 :         RSA *rtmp = NULL;
     753                 :            : #endif
     754                 :          0 :         EVP_PKEY *res = NULL;
     755                 :            : #ifndef OPENSSL_NO_RSA
     756                 :            :         HWCryptoHook_MPI e, n;
     757                 :            :         HWCryptoHook_RSAKeyHandle *hptr;
     758                 :            : #endif
     759                 :            : #if !defined(OPENSSL_NO_RSA)
     760                 :            :         char tempbuf[1024];
     761                 :            :         HWCryptoHook_ErrMsgBuf rmsg;
     762                 :            :         HWCryptoHook_PassphraseContext ppctx;
     763                 :            : #endif
     764                 :            : 
     765                 :            : #if !defined(OPENSSL_NO_RSA)
     766                 :          0 :         rmsg.buf = tempbuf;
     767                 :          0 :         rmsg.size = sizeof(tempbuf);
     768                 :            : #endif
     769                 :            : 
     770         [ #  # ]:          0 :         if(!hwcrhk_context)
     771                 :            :                 {
     772                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
     773                 :            :                         HWCRHK_R_NOT_INITIALISED);
     774                 :          0 :                 goto err;
     775                 :            :                 }
     776                 :            : #ifndef OPENSSL_NO_RSA
     777                 :          0 :         hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle));
     778         [ #  # ]:          0 :         if (!hptr)
     779                 :            :                 {
     780                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
     781                 :            :                         ERR_R_MALLOC_FAILURE);
     782                 :          0 :                 goto err;
     783                 :            :                 }
     784                 :          0 :         ppctx.ui_method = ui_method;
     785                 :          0 :         ppctx.callback_data = callback_data;
     786         [ #  # ]:          0 :         if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr,
     787                 :            :                 &rmsg, &ppctx))
     788                 :            :                 {
     789                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
     790                 :            :                         HWCRHK_R_CHIL_ERROR);
     791                 :          0 :                 ERR_add_error_data(1,rmsg.buf);
     792                 :          0 :                 goto err;
     793                 :            :                 }
     794         [ #  # ]:          0 :         if (!*hptr)
     795                 :            :                 {
     796                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
     797                 :            :                         HWCRHK_R_NO_KEY);
     798                 :          0 :                 goto err;
     799                 :            :                 }
     800                 :            : #endif
     801                 :            : #ifndef OPENSSL_NO_RSA
     802                 :          0 :         rtmp = RSA_new_method(eng);
     803                 :          0 :         RSA_set_ex_data(rtmp, hndidx_rsa, (char *)hptr);
     804                 :          0 :         rtmp->e = BN_new();
     805                 :          0 :         rtmp->n = BN_new();
     806                 :          0 :         rtmp->flags |= RSA_FLAG_EXT_PKEY;
     807                 :          0 :         MPI2BN(rtmp->e, e);
     808                 :          0 :         MPI2BN(rtmp->n, n);
     809         [ #  # ]:          0 :         if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)
     810                 :            :                 != HWCRYPTOHOOK_ERROR_MPISIZE)
     811                 :            :                 {
     812                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,HWCRHK_R_CHIL_ERROR);
     813                 :          0 :                 ERR_add_error_data(1,rmsg.buf);
     814                 :          0 :                 goto err;
     815                 :            :                 }
     816                 :            : 
     817                 :          0 :         bn_expand2(rtmp->e, e.size/sizeof(BN_ULONG));
     818                 :          0 :         bn_expand2(rtmp->n, n.size/sizeof(BN_ULONG));
     819                 :          0 :         MPI2BN(rtmp->e, e);
     820                 :          0 :         MPI2BN(rtmp->n, n);
     821                 :            : 
     822         [ #  # ]:          0 :         if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg))
     823                 :            :                 {
     824                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
     825                 :            :                         HWCRHK_R_CHIL_ERROR);
     826                 :          0 :                 ERR_add_error_data(1,rmsg.buf);
     827                 :          0 :                 goto err;
     828                 :            :                 }
     829                 :          0 :         rtmp->e->top = e.size / sizeof(BN_ULONG);
     830 [ #  # ][ #  # ]:          0 :         bn_fix_top(rtmp->e);
                 [ #  # ]
     831                 :          0 :         rtmp->n->top = n.size / sizeof(BN_ULONG);
     832 [ #  # ][ #  # ]:          0 :         bn_fix_top(rtmp->n);
                 [ #  # ]
     833                 :            : 
     834                 :          0 :         res = EVP_PKEY_new();
     835                 :          0 :         EVP_PKEY_assign_RSA(res, rtmp);
     836                 :            : #endif
     837                 :            : 
     838         [ #  # ]:          0 :         if (!res)
     839                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
     840                 :            :                         HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED);
     841                 :            : 
     842                 :          0 :         return res;
     843                 :            :  err:
     844                 :            : #ifndef OPENSSL_NO_RSA
     845         [ #  # ]:          0 :         if (rtmp)
     846                 :          0 :                 RSA_free(rtmp);
     847                 :            : #endif
     848                 :            :         return NULL;
     849                 :            :         }
     850                 :            : 
     851                 :          0 : static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
     852                 :            :         UI_METHOD *ui_method, void *callback_data)
     853                 :            :         {
     854                 :          0 :         EVP_PKEY *res = NULL;
     855                 :            : 
     856                 :            : #ifndef OPENSSL_NO_RSA
     857                 :          0 :         res = hwcrhk_load_privkey(eng, key_id,
     858                 :            :                 ui_method, callback_data);
     859                 :            : #endif
     860                 :            : 
     861         [ #  # ]:          0 :         if (res)
     862         [ #  # ]:          0 :                 switch(res->type)
     863                 :            :                         {
     864                 :            : #ifndef OPENSSL_NO_RSA
     865                 :            :                 case EVP_PKEY_RSA:
     866                 :            :                         {
     867                 :          0 :                         RSA *rsa = NULL;
     868                 :            : 
     869                 :          0 :                         CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
     870                 :          0 :                         rsa = res->pkey.rsa;
     871                 :          0 :                         res->pkey.rsa = RSA_new();
     872                 :          0 :                         res->pkey.rsa->n = rsa->n;
     873                 :          0 :                         res->pkey.rsa->e = rsa->e;
     874                 :          0 :                         rsa->n = NULL;
     875                 :          0 :                         rsa->e = NULL;
     876                 :          0 :                         CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
     877                 :          0 :                         RSA_free(rsa);
     878                 :            :                         }
     879                 :          0 :                         break;
     880                 :            : #endif
     881                 :            :                 default:
     882                 :          0 :                         HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
     883                 :            :                                 HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
     884                 :            :                         goto err;
     885                 :            :                         }
     886                 :            : 
     887                 :          0 :         return res;
     888                 :            :  err:
     889         [ #  # ]:          0 :         if (res)
     890                 :          0 :                 EVP_PKEY_free(res);
     891                 :            :         return NULL;
     892                 :            :         }
     893                 :            : 
     894                 :            : /* A little mod_exp */
     895                 :          0 : static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
     896                 :            :                         const BIGNUM *m, BN_CTX *ctx)
     897                 :            :         {
     898                 :            :         char tempbuf[1024];
     899                 :            :         HWCryptoHook_ErrMsgBuf rmsg;
     900                 :            :         /* Since HWCryptoHook_MPI is pretty compatible with BIGNUM's,
     901                 :            :            we use them directly, plus a little macro magic.  We only
     902                 :            :            thing we need to make sure of is that enough space is allocated. */
     903                 :            :         HWCryptoHook_MPI m_a, m_p, m_n, m_r;
     904                 :            :         int to_return, ret;
     905                 :            :  
     906                 :          0 :         to_return = 0; /* expect failure */
     907                 :          0 :         rmsg.buf = tempbuf;
     908                 :          0 :         rmsg.size = sizeof(tempbuf);
     909                 :            : 
     910         [ #  # ]:          0 :         if(!hwcrhk_context)
     911                 :            :                 {
     912                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_NOT_INITIALISED);
     913                 :            :                 goto err;
     914                 :            :                 }
     915                 :            :         /* Prepare the params */
     916                 :          0 :         bn_expand2(r, m->top);       /* Check for error !! */
     917                 :          0 :         BN2MPI(m_a, a);
     918                 :          0 :         BN2MPI(m_p, p);
     919                 :          0 :         BN2MPI(m_n, m);
     920                 :          0 :         MPI2BN(r, m_r);
     921                 :            : 
     922                 :            :         /* Perform the operation */
     923                 :          0 :         ret = p_hwcrhk_ModExp(hwcrhk_context, m_a, m_p, m_n, &m_r, &rmsg);
     924                 :            : 
     925                 :            :         /* Convert the response */
     926                 :          0 :         r->top = m_r.size / sizeof(BN_ULONG);
     927 [ #  # ][ #  # ]:          0 :         bn_fix_top(r);
                 [ #  # ]
     928                 :            : 
     929         [ #  # ]:          0 :         if (ret < 0)
     930                 :            :                 {
     931                 :            :                 /* FIXME: When this error is returned, HWCryptoHook is
     932                 :            :                    telling us that falling back to software computation
     933                 :            :                    might be a good thing. */
     934         [ #  # ]:          0 :                 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
     935                 :            :                         {
     936                 :          0 :                         HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FALLBACK);
     937                 :            :                         }
     938                 :            :                 else
     939                 :            :                         {
     940                 :          0 :                         HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FAILED);
     941                 :            :                         }
     942                 :          0 :                 ERR_add_error_data(1,rmsg.buf);
     943                 :            :                 goto err;
     944                 :            :                 }
     945                 :            : 
     946                 :            :         to_return = 1;
     947                 :            : err:
     948                 :          0 :         return to_return;
     949                 :            :         }
     950                 :            : 
     951                 :            : #ifndef OPENSSL_NO_RSA 
     952                 :          0 : static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
     953                 :            :         {
     954                 :            :         char tempbuf[1024];
     955                 :            :         HWCryptoHook_ErrMsgBuf rmsg;
     956                 :            :         HWCryptoHook_RSAKeyHandle *hptr;
     957                 :          0 :         int to_return = 0, ret;
     958                 :            : 
     959                 :          0 :         rmsg.buf = tempbuf;
     960                 :          0 :         rmsg.size = sizeof(tempbuf);
     961                 :            : 
     962         [ #  # ]:          0 :         if(!hwcrhk_context)
     963                 :            :                 {
     964                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,HWCRHK_R_NOT_INITIALISED);
     965                 :          0 :                 goto err;
     966                 :            :                 }
     967                 :            : 
     968                 :            :         /* This provides support for nForce keys.  Since that's opaque data
     969                 :            :            all we do is provide a handle to the proper key and let HWCryptoHook
     970                 :            :            take care of the rest. */
     971         [ #  # ]:          0 :         if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx_rsa))
     972                 :            :                 != NULL)
     973                 :            :                 {
     974                 :            :                 HWCryptoHook_MPI m_a, m_r;
     975                 :            : 
     976         [ #  # ]:          0 :                 if(!rsa->n)
     977                 :            :                         {
     978                 :          0 :                         HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
     979                 :            :                                 HWCRHK_R_MISSING_KEY_COMPONENTS);
     980                 :          0 :                         goto err;
     981                 :            :                         }
     982                 :            : 
     983                 :            :                 /* Prepare the params */
     984                 :          0 :                 bn_expand2(r, rsa->n->top); /* Check for error !! */
     985                 :          0 :                 BN2MPI(m_a, I);
     986                 :          0 :                 MPI2BN(r, m_r);
     987                 :            : 
     988                 :            :                 /* Perform the operation */
     989                 :          0 :                 ret = p_hwcrhk_RSA(m_a, *hptr, &m_r, &rmsg);
     990                 :            : 
     991                 :            :                 /* Convert the response */
     992                 :          0 :                 r->top = m_r.size / sizeof(BN_ULONG);
     993 [ #  # ][ #  # ]:          0 :                 bn_fix_top(r);
                 [ #  # ]
     994                 :            : 
     995         [ #  # ]:          0 :                 if (ret < 0)
     996                 :            :                         {
     997                 :            :                         /* FIXME: When this error is returned, HWCryptoHook is
     998                 :            :                            telling us that falling back to software computation
     999                 :            :                            might be a good thing. */
    1000         [ #  # ]:          0 :                         if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
    1001                 :            :                                 {
    1002                 :          0 :                                 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
    1003                 :            :                                         HWCRHK_R_REQUEST_FALLBACK);
    1004                 :            :                                 }
    1005                 :            :                         else
    1006                 :            :                                 {
    1007                 :          0 :                                 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
    1008                 :            :                                         HWCRHK_R_REQUEST_FAILED);
    1009                 :            :                                 }
    1010                 :          0 :                         ERR_add_error_data(1,rmsg.buf);
    1011                 :          0 :                         goto err;
    1012                 :            :                         }
    1013                 :            :                 }
    1014                 :            :         else
    1015                 :            :                 {
    1016                 :            :                 HWCryptoHook_MPI m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, m_r;
    1017                 :            : 
    1018 [ #  # ][ #  # ]:          0 :                 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
         [ #  # ][ #  # ]
                 [ #  # ]
    1019                 :            :                         {
    1020                 :          0 :                         HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
    1021                 :            :                                 HWCRHK_R_MISSING_KEY_COMPONENTS);
    1022                 :          0 :                         goto err;
    1023                 :            :                         }
    1024                 :            : 
    1025                 :            :                 /* Prepare the params */
    1026                 :          0 :                 bn_expand2(r, rsa->n->top); /* Check for error !! */
    1027                 :          0 :                 BN2MPI(m_a, I);
    1028                 :          0 :                 BN2MPI(m_p, rsa->p);
    1029                 :          0 :                 BN2MPI(m_q, rsa->q);
    1030                 :          0 :                 BN2MPI(m_dmp1, rsa->dmp1);
    1031                 :          0 :                 BN2MPI(m_dmq1, rsa->dmq1);
    1032                 :          0 :                 BN2MPI(m_iqmp, rsa->iqmp);
    1033                 :          0 :                 MPI2BN(r, m_r);
    1034                 :            : 
    1035                 :            :                 /* Perform the operation */
    1036                 :          0 :                 ret = p_hwcrhk_ModExpCRT(hwcrhk_context, m_a, m_p, m_q,
    1037                 :            :                         m_dmp1, m_dmq1, m_iqmp, &m_r, &rmsg);
    1038                 :            : 
    1039                 :            :                 /* Convert the response */
    1040                 :          0 :                 r->top = m_r.size / sizeof(BN_ULONG);
    1041 [ #  # ][ #  # ]:          0 :                 bn_fix_top(r);
                 [ #  # ]
    1042                 :            : 
    1043         [ #  # ]:          0 :                 if (ret < 0)
    1044                 :            :                         {
    1045                 :            :                         /* FIXME: When this error is returned, HWCryptoHook is
    1046                 :            :                            telling us that falling back to software computation
    1047                 :            :                            might be a good thing. */
    1048         [ #  # ]:          0 :                         if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
    1049                 :            :                                 {
    1050                 :          0 :                                 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
    1051                 :            :                                         HWCRHK_R_REQUEST_FALLBACK);
    1052                 :            :                                 }
    1053                 :            :                         else
    1054                 :            :                                 {
    1055                 :          0 :                                 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
    1056                 :            :                                         HWCRHK_R_REQUEST_FAILED);
    1057                 :            :                                 }
    1058                 :          0 :                         ERR_add_error_data(1,rmsg.buf);
    1059                 :          0 :                         goto err;
    1060                 :            :                         }
    1061                 :            :                 }
    1062                 :            :         /* If we're here, we must be here with some semblance of success :-) */
    1063                 :            :         to_return = 1;
    1064                 :            : err:
    1065                 :          0 :         return to_return;
    1066                 :            :         }
    1067                 :            : #endif
    1068                 :            : 
    1069                 :            : #ifndef OPENSSL_NO_RSA
    1070                 :            : /* This function is aliased to mod_exp (with the mont stuff dropped). */
    1071                 :          0 : static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
    1072                 :            :                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
    1073                 :            :         {
    1074                 :          0 :         return hwcrhk_mod_exp(r, a, p, m, ctx);
    1075                 :            :         }
    1076                 :            : 
    1077                 :          0 : static int hwcrhk_rsa_finish(RSA *rsa)
    1078                 :            :         {
    1079                 :            :         HWCryptoHook_RSAKeyHandle *hptr;
    1080                 :            : 
    1081                 :          0 :         hptr = RSA_get_ex_data(rsa, hndidx_rsa);
    1082         [ #  # ]:          0 :         if (hptr)
    1083                 :            :                 {
    1084                 :          0 :                 p_hwcrhk_RSAUnloadKey(*hptr, NULL);
    1085                 :          0 :                 OPENSSL_free(hptr);
    1086                 :          0 :                 RSA_set_ex_data(rsa, hndidx_rsa, NULL);
    1087                 :            :                 }
    1088                 :          0 :         return 1;
    1089                 :            :         }
    1090                 :            : 
    1091                 :            : #endif
    1092                 :            : 
    1093                 :            : #ifndef OPENSSL_NO_DH
    1094                 :            : /* This function is aliased to mod_exp (with the dh and mont dropped). */
    1095                 :          0 : static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
    1096                 :            :                 const BIGNUM *a, const BIGNUM *p,
    1097                 :            :                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
    1098                 :            :         {
    1099                 :          0 :         return hwcrhk_mod_exp(r, a, p, m, ctx);
    1100                 :            :         }
    1101                 :            : #endif
    1102                 :            : 
    1103                 :            : /* Random bytes are good */
    1104                 :          0 : static int hwcrhk_rand_bytes(unsigned char *buf, int num)
    1105                 :            :         {
    1106                 :            :         char tempbuf[1024];
    1107                 :            :         HWCryptoHook_ErrMsgBuf rmsg;
    1108                 :          0 :         int to_return = 0; /* assume failure */
    1109                 :            :         int ret;
    1110                 :            : 
    1111                 :          0 :         rmsg.buf = tempbuf;
    1112                 :          0 :         rmsg.size = sizeof(tempbuf);
    1113                 :            : 
    1114         [ #  # ]:          0 :         if(!hwcrhk_context)
    1115                 :            :                 {
    1116                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,HWCRHK_R_NOT_INITIALISED);
    1117                 :          0 :                 goto err;
    1118                 :            :                 }
    1119                 :            : 
    1120                 :          0 :         ret = p_hwcrhk_RandomBytes(hwcrhk_context, buf, num, &rmsg);
    1121         [ #  # ]:          0 :         if (ret < 0)
    1122                 :            :                 {
    1123                 :            :                 /* FIXME: When this error is returned, HWCryptoHook is
    1124                 :            :                    telling us that falling back to software computation
    1125                 :            :                    might be a good thing. */
    1126         [ #  # ]:          0 :                 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
    1127                 :            :                         {
    1128                 :          0 :                         HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
    1129                 :            :                                 HWCRHK_R_REQUEST_FALLBACK);
    1130                 :            :                         }
    1131                 :            :                 else
    1132                 :            :                         {
    1133                 :          0 :                         HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
    1134                 :            :                                 HWCRHK_R_REQUEST_FAILED);
    1135                 :            :                         }
    1136                 :          0 :                 ERR_add_error_data(1,rmsg.buf);
    1137                 :          0 :                 goto err;
    1138                 :            :                 }
    1139                 :            :         to_return = 1;
    1140                 :            :  err:
    1141                 :          0 :         return to_return;
    1142                 :            :         }
    1143                 :            : 
    1144                 :          0 : static int hwcrhk_rand_status(void)
    1145                 :            :         {
    1146                 :          0 :         return 1;
    1147                 :            :         }
    1148                 :            : 
    1149                 :            : /* Mutex calls: since the HWCryptoHook model closely follows the POSIX model
    1150                 :            :  * these just wrap the POSIX functions and add some logging.
    1151                 :            :  */
    1152                 :            : 
    1153                 :          0 : static int hwcrhk_mutex_init(HWCryptoHook_Mutex* mt,
    1154                 :            :         HWCryptoHook_CallerContext *cactx)
    1155                 :            :         {
    1156                 :          0 :         mt->lockid = CRYPTO_get_new_dynlockid();
    1157         [ #  # ]:          0 :         if (mt->lockid == 0)
    1158                 :            :                 return 1; /* failure */
    1159                 :          0 :         return 0; /* success */
    1160                 :            :         }
    1161                 :            : 
    1162                 :          0 : static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt)
    1163                 :            :         {
    1164                 :          0 :         CRYPTO_w_lock(mt->lockid);
    1165                 :          0 :         return 0;
    1166                 :            :         }
    1167                 :            : 
    1168                 :          0 : static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt)
    1169                 :            :         {
    1170                 :          0 :         CRYPTO_w_unlock(mt->lockid);
    1171                 :          0 :         }
    1172                 :            : 
    1173                 :          0 : static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex *mt)
    1174                 :            :         {
    1175                 :          0 :         CRYPTO_destroy_dynlockid(mt->lockid);
    1176                 :          0 :         }
    1177                 :            : 
    1178                 :          0 : static int hwcrhk_get_pass(const char *prompt_info,
    1179                 :            :         int *len_io, char *buf,
    1180                 :            :         HWCryptoHook_PassphraseContext *ppctx,
    1181                 :            :         HWCryptoHook_CallerContext *cactx)
    1182                 :            :         {
    1183                 :          0 :         pem_password_cb *callback = NULL;
    1184                 :          0 :         void *callback_data = NULL;
    1185                 :          0 :         UI_METHOD *ui_method = NULL;
    1186                 :            :         /* Despite what the documentation says prompt_info can be
    1187                 :            :          * an empty string.
    1188                 :            :          */
    1189 [ #  # ][ #  # ]:          0 :         if (prompt_info && !*prompt_info)
    1190                 :          0 :                 prompt_info = NULL;
    1191                 :            : 
    1192         [ #  # ]:          0 :         if (cactx)
    1193                 :            :                 {
    1194         [ #  # ]:          0 :                 if (cactx->ui_method)
    1195                 :          0 :                         ui_method = cactx->ui_method;
    1196         [ #  # ]:          0 :                 if (cactx->password_callback)
    1197                 :          0 :                         callback = cactx->password_callback;
    1198         [ #  # ]:          0 :                 if (cactx->callback_data)
    1199                 :          0 :                         callback_data = cactx->callback_data;
    1200                 :            :                 }
    1201         [ #  # ]:          0 :         if (ppctx)
    1202                 :            :                 {
    1203         [ #  # ]:          0 :                 if (ppctx->ui_method)
    1204                 :            :                         {
    1205                 :          0 :                         ui_method = ppctx->ui_method;
    1206                 :          0 :                         callback = NULL;
    1207                 :            :                         }
    1208         [ #  # ]:          0 :                 if (ppctx->callback_data)
    1209                 :          0 :                         callback_data = ppctx->callback_data;
    1210                 :            :                 }
    1211         [ #  # ]:          0 :         if (callback == NULL && ui_method == NULL)
    1212                 :            :                 {
    1213                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_GET_PASS,HWCRHK_R_NO_CALLBACK);
    1214                 :          0 :                 return -1;
    1215                 :            :                 }
    1216                 :            : 
    1217         [ #  # ]:          0 :         if (ui_method)
    1218                 :            :                 {
    1219                 :          0 :                 UI *ui = UI_new_method(ui_method);
    1220         [ #  # ]:          0 :                 if (ui)
    1221                 :            :                         {
    1222                 :            :                         int ok;
    1223                 :          0 :                         char *prompt = UI_construct_prompt(ui,
    1224                 :            :                                 "pass phrase", prompt_info);
    1225                 :            : 
    1226                 :          0 :                         ok = UI_add_input_string(ui,prompt,
    1227                 :            :                                 UI_INPUT_FLAG_DEFAULT_PWD,
    1228                 :          0 :                                 buf,0,(*len_io) - 1);
    1229                 :          0 :                         UI_add_user_data(ui, callback_data);
    1230                 :          0 :                         UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
    1231                 :            : 
    1232         [ #  # ]:          0 :                         if (ok >= 0)
    1233                 :            :                                 do
    1234                 :            :                                         {
    1235                 :          0 :                                         ok=UI_process(ui);
    1236                 :            :                                         }
    1237 [ #  # ][ #  # ]:          0 :                                 while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
    1238                 :            : 
    1239         [ #  # ]:          0 :                         if (ok >= 0)
    1240                 :          0 :                                 *len_io = strlen(buf);
    1241                 :            : 
    1242                 :          0 :                         UI_free(ui);
    1243                 :          0 :                         OPENSSL_free(prompt);
    1244                 :            :                         }
    1245                 :            :                 }
    1246                 :            :         else
    1247                 :            :                 {
    1248                 :          0 :                 *len_io = callback(buf, *len_io, 0, callback_data);
    1249                 :            :                 }
    1250         [ #  # ]:          0 :         if(!*len_io)
    1251                 :            :                 return -1;
    1252                 :          0 :         return 0;
    1253                 :            :         }
    1254                 :            : 
    1255                 :          0 : static int hwcrhk_insert_card(const char *prompt_info,
    1256                 :            :                       const char *wrong_info,
    1257                 :            :                       HWCryptoHook_PassphraseContext *ppctx,
    1258                 :            :                       HWCryptoHook_CallerContext *cactx)
    1259                 :            :         {
    1260                 :          0 :         int ok = -1;
    1261                 :            :         UI *ui;
    1262                 :          0 :         void *callback_data = NULL;
    1263                 :          0 :         UI_METHOD *ui_method = NULL;
    1264                 :            : 
    1265         [ #  # ]:          0 :         if (cactx)
    1266                 :            :                 {
    1267         [ #  # ]:          0 :                 if (cactx->ui_method)
    1268                 :          0 :                         ui_method = cactx->ui_method;
    1269         [ #  # ]:          0 :                 if (cactx->callback_data)
    1270                 :          0 :                         callback_data = cactx->callback_data;
    1271                 :            :                 }
    1272         [ #  # ]:          0 :         if (ppctx)
    1273                 :            :                 {
    1274         [ #  # ]:          0 :                 if (ppctx->ui_method)
    1275                 :          0 :                         ui_method = ppctx->ui_method;
    1276         [ #  # ]:          0 :                 if (ppctx->callback_data)
    1277                 :          0 :                         callback_data = ppctx->callback_data;
    1278                 :            :                 }
    1279         [ #  # ]:          0 :         if (ui_method == NULL)
    1280                 :            :                 {
    1281                 :          0 :                 HWCRHKerr(HWCRHK_F_HWCRHK_INSERT_CARD,
    1282                 :            :                         HWCRHK_R_NO_CALLBACK);
    1283                 :          0 :                 return -1;
    1284                 :            :                 }
    1285                 :            : 
    1286                 :          0 :         ui = UI_new_method(ui_method);
    1287                 :            : 
    1288         [ #  # ]:          0 :         if (ui)
    1289                 :            :                 {
    1290                 :            :                 char answer;
    1291                 :            :                 char buf[BUFSIZ];
    1292                 :            :                 /* Despite what the documentation says wrong_info can be
    1293                 :            :                  * an empty string.
    1294                 :            :                  */
    1295 [ #  # ][ #  # ]:          0 :                 if (wrong_info && *wrong_info)
    1296                 :          0 :                         BIO_snprintf(buf, sizeof(buf)-1,
    1297                 :            :                                 "Current card: \"%s\"\n", wrong_info);
    1298                 :            :                 else
    1299                 :          0 :                         buf[0] = 0;
    1300                 :          0 :                 ok = UI_dup_info_string(ui, buf);
    1301         [ #  # ]:          0 :                 if (ok >= 0 && prompt_info)
    1302                 :            :                         {
    1303                 :          0 :                         BIO_snprintf(buf, sizeof(buf)-1,
    1304                 :            :                                 "Insert card \"%s\"", prompt_info);
    1305                 :          0 :                         ok = UI_dup_input_boolean(ui, buf,
    1306                 :            :                                 "\n then hit <enter> or C<enter> to cancel\n",
    1307                 :            :                                 "\r\n", "Cc", UI_INPUT_FLAG_ECHO, &answer);
    1308                 :            :                         }
    1309                 :          0 :                 UI_add_user_data(ui, callback_data);
    1310                 :            : 
    1311         [ #  # ]:          0 :                 if (ok >= 0)
    1312                 :          0 :                         ok = UI_process(ui);
    1313                 :          0 :                 UI_free(ui);
    1314                 :            : 
    1315 [ #  # ][ #  # ]:          0 :                 if (ok == -2 || (ok >= 0 && answer == 'C'))
                 [ #  # ]
    1316                 :            :                         ok = 1;
    1317         [ #  # ]:          0 :                 else if (ok < 0)
    1318                 :            :                         ok = -1;
    1319                 :            :                 else
    1320                 :          0 :                         ok = 0;
    1321                 :            :                 }
    1322                 :          0 :         return ok;
    1323                 :            :         }
    1324                 :            : 
    1325                 :          0 : static void hwcrhk_log_message(void *logstr, const char *message)
    1326                 :            :         {
    1327                 :          0 :         BIO *lstream = NULL;
    1328                 :            : 
    1329                 :          0 :         CRYPTO_w_lock(CRYPTO_LOCK_BIO);
    1330         [ #  # ]:          0 :         if (logstr)
    1331                 :          0 :                 lstream=*(BIO **)logstr;
    1332         [ #  # ]:          0 :         if (lstream)
    1333                 :            :                 {
    1334                 :          0 :                 BIO_printf(lstream, "%s\n", message);
    1335                 :            :                 }
    1336                 :          0 :         CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
    1337                 :          0 :         }
    1338                 :            : 
    1339                 :            : /* This stuff is needed if this ENGINE is being compiled into a self-contained
    1340                 :            :  * shared-library. */      
    1341                 :            : #ifndef OPENSSL_NO_DYNAMIC_ENGINE
    1342                 :            : static int bind_fn(ENGINE *e, const char *id)
    1343                 :            :         {
    1344                 :            :         if(id && (strcmp(id, engine_hwcrhk_id) != 0) &&
    1345                 :            :                         (strcmp(id, engine_hwcrhk_id_alt) != 0))
    1346                 :            :                 return 0;
    1347                 :            :         if(!bind_helper(e))
    1348                 :            :                 return 0;
    1349                 :            :         return 1;
    1350                 :            :         }       
    1351                 :            : IMPLEMENT_DYNAMIC_CHECK_FN()
    1352                 :            : IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
    1353                 :            : #endif /* OPENSSL_NO_DYNAMIC_ENGINE */
    1354                 :            : 
    1355                 :            : #endif /* !OPENSSL_NO_HW_CHIL */
    1356                 :            : #endif /* !OPENSSL_NO_HW */

Generated by: LCOV version 1.9