PKCS#8 support for alternative PRFs.
[openssl.git] / engines / e_chil.c
index 14654a783325190f55090b4b997537927bab5c8f..fdc2100e3de006dde3a9fec29b0672b69f3a67ae 100644 (file)
@@ -1,6 +1,6 @@
-/* crypto/engine/hw_ncipher.c -*- mode: C; c-file-style: "eay" -*- */
+/* crypto/engine/e_chil.c -*- mode: C; c-file-style: "eay" -*- */
 /* Written by Richard Levitte (richard@levitte.org), Geoff Thorpe
- * (geoff@geoffthorpe.net) and Dr Stephen N Henson (shenson@bigfoot.com)
+ * (geoff@geoffthorpe.net) and Dr Stephen N Henson (steve@openssl.org)
  * for the OpenSSL project 2000.
  */
 /* ====================================================================
 #include <openssl/engine.h>
 #include <openssl/ui.h>
 #include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
 #include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
 #include <openssl/dh.h>
+#endif
 #include <openssl/bn.h>
 
 #ifndef OPENSSL_NO_HW
-#ifndef OPENSSL_NO_HW_NCIPHER
+#ifndef OPENSSL_NO_HW_CHIL
 
 /* Attribution notice: nCipher have said several times that it's OK for
  * us to implement a general interface to their boxes, and recently declared
@@ -86,7 +90,7 @@
 #include "vendor_defns/hwcryptohook.h"
 #endif
 
-#define HWCRHK_LIB_NAME "hwcrhk engine"
+#define HWCRHK_LIB_NAME "CHIL engine"
 #include "e_chil_err.c"
 
 static int hwcrhk_destroy(ENGINE *e);
@@ -107,10 +111,11 @@ static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
 #ifndef OPENSSL_NO_RSA
 /* RSA stuff */
 static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
-#endif
 /* This function is aliased to mod_exp (with the mont stuff dropped). */
 static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+static int hwcrhk_rsa_finish(RSA *rsa);
+#endif
 
 #ifndef OPENSSL_NO_DH
 /* DH stuff */
@@ -129,8 +134,6 @@ static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
        UI_METHOD *ui_method, void *callback_data);
 static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
        UI_METHOD *ui_method, void *callback_data);
-static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
-       int ind,long argl, void *argp);
 
 /* Interaction stuff */
 static int hwcrhk_insert_card(const char *prompt_info,
@@ -156,11 +159,11 @@ static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = {
                ENGINE_CMD_FLAG_STRING},
        {HWCRHK_CMD_FORK_CHECK,
                "FORK_CHECK",
-               "Turns fork() checking on or off (boolean)",
+               "Turns fork() checking on (non-zero) or off (zero)",
                ENGINE_CMD_FLAG_NUMERIC},
        {HWCRHK_CMD_THREAD_LOCKING,
                "THREAD_LOCKING",
-               "Turns thread-safe locking on or off (boolean)",
+               "Turns thread-safe locking on (zero) or off (non-zero)",
                ENGINE_CMD_FLAG_NUMERIC},
        {HWCRHK_CMD_SET_USER_INTERFACE,
                "SET_USER_INTERFACE",
@@ -177,7 +180,7 @@ static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = {
 /* Our internal RSA_METHOD that we provide pointers to */
 static RSA_METHOD hwcrhk_rsa =
        {
-       "nCipher RSA method",
+       "CHIL RSA method",
        NULL,
        NULL,
        NULL,
@@ -185,7 +188,7 @@ static RSA_METHOD hwcrhk_rsa =
        hwcrhk_rsa_mod_exp,
        hwcrhk_mod_exp_mont,
        NULL,
-       NULL,
+       hwcrhk_rsa_finish,
        0,
        NULL,
        NULL,
@@ -198,7 +201,7 @@ static RSA_METHOD hwcrhk_rsa =
 /* Our internal DH_METHOD that we provide pointers to */
 static DH_METHOD hwcrhk_dh =
        {
-       "nCipher DH method",
+       "CHIL DH method",
        NULL,
        NULL,
        hwcrhk_mod_exp_dh,
@@ -212,7 +215,7 @@ static DH_METHOD hwcrhk_dh =
 
 static RAND_METHOD hwcrhk_rand =
        {
-       /* "nCipher RAND method", */
+       /* "CHIL RAND method", */
        NULL,
        hwcrhk_rand_bytes,
        NULL,
@@ -223,9 +226,11 @@ static RAND_METHOD hwcrhk_rand =
 
 /* Constants used when creating the ENGINE */
 static const char *engine_hwcrhk_id = "chil";
-static const char *engine_hwcrhk_name = "nCipher hardware engine support";
+static const char *engine_hwcrhk_name = "CHIL hardware engine support";
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE 
 /* Compatibility hack, the dynamic library uses this form in the path */
 static const char *engine_hwcrhk_id_alt = "ncipher";
+#endif
 
 /* Internal stuff for HWCryptoHook */
 
@@ -325,7 +330,7 @@ static HWCryptoHook_InitInfo hwcrhk_globals = {
 
 /* Now, to our own code */
 
-/* This internal function is used by ENGINE_ncipher() and possibly by the
+/* This internal function is used by ENGINE_chil() and possibly by the
  * "dynamic" ENGINE support too */
 static int bind_helper(ENGINE *e)
        {
@@ -381,7 +386,7 @@ static int bind_helper(ENGINE *e)
        }
 
 #ifdef OPENSSL_NO_DYNAMIC_ENGINE
-static ENGINE *engine_ncipher(void)
+static ENGINE *engine_chil(void)
        {
        ENGINE *ret = ENGINE_new();
        if(!ret)
@@ -397,7 +402,7 @@ static ENGINE *engine_ncipher(void)
 void ENGINE_load_chil(void)
        {
        /* Copied from eng_[openssl|dyn].c */
-       ENGINE *toadd = engine_ncipher();
+       ENGINE *toadd = engine_chil();
        if(!toadd) return;
        ENGINE_add(toadd);
        ENGINE_free(toadd);
@@ -493,7 +498,7 @@ static void release_context(HWCryptoHook_ContextHandle hac)
        p_hwcrhk_Finish(hac);
        }
 
-/* Destructor (complements the "ENGINE_ncipher()" constructor) */
+/* Destructor (complements the "ENGINE_chil()" constructor) */
 static int hwcrhk_destroy(ENGINE *e)
        {
        free_HWCRHK_LIBNAME();
@@ -578,12 +583,6 @@ static int hwcrhk_init(ENGINE *e)
                        hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock;
                        hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy;
                        }
-               else if (CRYPTO_get_locking_callback() != NULL)
-                       {
-                       HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_LOCKING_MISSING);
-                       ERR_add_error_data(1,"You HAVE to add dynamic locking callbacks via CRYPTO_set_dynlock_{create,lock,destroy}_callback()");
-                       goto err;
-                       }
                }
 
        /* Try and get a context - if not, we may have a DSO but no
@@ -598,7 +597,7 @@ static int hwcrhk_init(ENGINE *e)
        if (hndidx_rsa == -1)
                hndidx_rsa = RSA_get_ex_new_index(0,
                        "nFast HWCryptoHook RSA key handle",
-                       NULL, NULL, hwcrhk_ex_free);
+                       NULL, NULL, NULL);
 #endif
        return 1;
 err:
@@ -760,8 +759,8 @@ static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
 #if !defined(OPENSSL_NO_RSA)
        char tempbuf[1024];
        HWCryptoHook_ErrMsgBuf rmsg;
-#endif
        HWCryptoHook_PassphraseContext ppctx;
+#endif
 
 #if !defined(OPENSSL_NO_RSA)
        rmsg.buf = tempbuf;
@@ -842,8 +841,6 @@ static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
 
        return res;
  err:
-       if (res)
-               EVP_PKEY_free(res);
 #ifndef OPENSSL_NO_RSA
        if (rtmp)
                RSA_free(rtmp);
@@ -1069,6 +1066,7 @@ err:
        }
 #endif
 
+#ifndef OPENSSL_NO_RSA
 /* This function is aliased to mod_exp (with the mont stuff dropped). */
 static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
@@ -1076,6 +1074,22 @@ static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        return hwcrhk_mod_exp(r, a, p, m, ctx);
        }
 
+static int hwcrhk_rsa_finish(RSA *rsa)
+       {
+       HWCryptoHook_RSAKeyHandle *hptr;
+
+       hptr = RSA_get_ex_data(rsa, hndidx_rsa);
+       if (hptr)
+                {
+                p_hwcrhk_RSAUnloadKey(*hptr, NULL);
+                OPENSSL_free(hptr);
+               RSA_set_ex_data(rsa, hndidx_rsa, NULL);
+                }
+       return 1;
+       }
+
+#endif
+
 #ifndef OPENSSL_NO_DH
 /* This function is aliased to mod_exp (with the dh and mont dropped). */
 static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
@@ -1132,33 +1146,6 @@ static int hwcrhk_rand_status(void)
        return 1;
        }
 
-/* This cleans up an RSA KM key, called when ex_data is freed */
-
-static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
-       int ind,long argl, void *argp)
-{
-       char tempbuf[1024];
-       HWCryptoHook_ErrMsgBuf rmsg;
-#ifndef OPENSSL_NO_RSA
-       HWCryptoHook_RSAKeyHandle *hptr;
-#endif
-#if !defined(OPENSSL_NO_RSA)
-       int ret;
-#endif
-
-       rmsg.buf = tempbuf;
-       rmsg.size = sizeof(tempbuf);
-
-#ifndef OPENSSL_NO_RSA
-       hptr = (HWCryptoHook_RSAKeyHandle *) item;
-       if(hptr)
-                {
-                ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL);
-                OPENSSL_free(hptr);
-                }
-#endif
-}
-
 /* Mutex calls: since the HWCryptoHook model closely follows the POSIX model
  * these just wrap the POSIX functions and add some logging.
  */
@@ -1196,6 +1183,11 @@ static int hwcrhk_get_pass(const char *prompt_info,
        pem_password_cb *callback = NULL;
        void *callback_data = NULL;
         UI_METHOD *ui_method = NULL;
+       /* Despite what the documentation says prompt_info can be
+        * an empty string.
+        */
+       if (prompt_info && !*prompt_info)
+               prompt_info = NULL;
 
         if (cactx)
                 {
@@ -1297,10 +1289,14 @@ static int hwcrhk_insert_card(const char *prompt_info,
                {
                char answer;
                char buf[BUFSIZ];
-
-               if (wrong_info)
+               /* Despite what the documentation says wrong_info can be
+                * an empty string.
+                */
+               if (wrong_info && *wrong_info)
                        BIO_snprintf(buf, sizeof(buf)-1,
                                "Current card: \"%s\"\n", wrong_info);
+               else
+                       buf[0] = 0;
                ok = UI_dup_info_string(ui, buf);
                if (ok >= 0 && prompt_info)
                        {
@@ -1356,5 +1352,5 @@ IMPLEMENT_DYNAMIC_CHECK_FN()
 IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
 #endif /* OPENSSL_NO_DYNAMIC_ENGINE */
 
-#endif /* !OPENSSL_NO_HW_NCIPHER */
+#endif /* !OPENSSL_NO_HW_CHIL */
 #endif /* !OPENSSL_NO_HW */