diff --git a/CHANGES b/CHANGES index 054106296f5e45125406681c849a141cadd4552e..761cd4596c5ece294d9baca39396b84172809b55 100644 --- a/CHANGES +++ b/CHANGES @@ -43,6 +43,14 @@ *) applies to 0.9.6a ... 0.9.6d and 0.9.7 +) applies to 0.9.7 only + +) Add an "init" command to the ENGINE config module and auto initialize + ENGINEs. Without any "init" command the ENGINE will be initialized + after all ctrl commands have been executed on it. If init=1 the + ENGINE is initailized at that point (ctrls before that point are run + on the uninitialized ENGINE and after on the initialized one). If + init=0 then the ENGINE will not be iniatialized at all. + [Steve Henson] + +) Fix the 'app_verify_callback' interface so that the user-defined argument is actually passed to the callback: In the SSL_CTX_set_cert_verify_callback() prototype, the callback diff --git a/apps/apps.h b/apps/apps.h index 24aa447117ea049acf1cd1701bde8000784d1b66..a05ba712be8661b7c2558339ff9f3a061b5699f4 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -195,10 +195,10 @@ extern BIO *bio_err; setup_ui_method(); } while(0) # endif # define apps_shutdown() \ - do { destroy_ui_method(); EVP_cleanup(); \ - ENGINE_cleanup(); CRYPTO_cleanup_all_ex_data(); \ - ERR_remove_state(0); ERR_free_strings(); \ - CONF_modules_unload(1); } while(0) + do { CONF_modules_unload(1); destroy_ui_method(); \ + EVP_cleanup(); ENGINE_cleanup(); \ + CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); \ + ERR_free_strings(); } while(0) #endif typedef struct args_st diff --git a/apps/dhparam.c b/apps/dhparam.c index f1664a59b7acc9f7f558980734f7208fe8bafe41..ea15ef32368f66abcf45b6575727f47d9d9c83c5 100644 --- a/apps/dhparam.c +++ b/apps/dhparam.c @@ -490,7 +490,7 @@ bad: printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); printf("\t\t{ DH_free(dh); return(NULL); }\n"); if (dh->length) - printf("\tdh->length = %d;\n", dh->length); + printf("\tdh->length = %ld;\n", dh->length); printf("\treturn(dh);\n\t}\n"); OPENSSL_free(data); } diff --git a/crypto/engine/eng_cnf.c b/crypto/engine/eng_cnf.c index d8d3092f0de63cca55b5f3acf47a2a231674e4ae..8c0ae8a1ad3c9a5f07c53adc4e77e38d4a7e3f76 100644 --- a/crypto/engine/eng_cnf.c +++ b/crypto/engine/eng_cnf.c @@ -75,10 +75,28 @@ static char *skip_dot(char *name) return name; } +static STACK_OF(ENGINE) *initialized_engines = NULL; + +static int int_engine_init(ENGINE *e) + { + if (!ENGINE_init(e)) + return 0; + if (!initialized_engines) + initialized_engines = sk_ENGINE_new_null(); + if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e)) + { + ENGINE_finish(e); + return 0; + } + return 1; + } + + int int_engine_configure(char *name, char *value, const CONF *cnf) { int i; int ret = 0; + long do_init = -1; STACK_OF(CONF_VALUE) *ecmds; CONF_VALUE *ecmd; char *ctrlname, *ctrlvalue; @@ -140,7 +158,22 @@ int int_engine_configure(char *name, char *value, const CONF *cnf) */ if (!strcmp(ctrlvalue, "EMPTY")) ctrlvalue = NULL; - if (!strcmp(ctrlname, "default_algorithms")) + else if (!strcmp(ctrlname, "init")) + { + if (!NCONF_get_number_e(cnf, value, "init", &do_init)) + goto err; + if (do_init == 1) + { + if (!int_engine_init(e)) + goto err; + } + else if (do_init != 0) + { + ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_INVALID_INIT_VALUE); + goto err; + } + } + else if (!strcmp(ctrlname, "default_algorithms")) { if (!ENGINE_set_default_string(e, ctrlvalue)) goto err; @@ -151,7 +184,10 @@ int int_engine_configure(char *name, char *value, const CONF *cnf) } + } + if (e && (do_init == -1) && !int_engine_init(e)) + goto err; ret = 1; err: if (e) @@ -188,7 +224,19 @@ static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf) return 1; } +static void int_engine_module_finish(CONF_IMODULE *md) + { + ENGINE *e; + while ((e = sk_ENGINE_pop(initialized_engines))) + ENGINE_finish(e); + sk_ENGINE_free(initialized_engines); + initialized_engines = NULL; + } + + void ENGINE_add_conf_module(void) { - CONF_module_add("engines", int_engine_module_init, 0); + CONF_module_add("engines", + int_engine_module_init, + int_engine_module_finish); } diff --git a/crypto/engine/eng_err.c b/crypto/engine/eng_err.c index fa59c8727c39045362867e91b06d7e7ec7fbf463..f6c56303959ab80acfa353dc0853b461c41a0a7a 100644 --- a/crypto/engine/eng_err.c +++ b/crypto/engine/eng_err.c @@ -129,6 +129,7 @@ static ERR_STRING_DATA ENGINE_str_reasons[]= {ENGINE_R_INVALID_ARGUMENT ,"invalid argument"}, {ENGINE_R_INVALID_CMD_NAME ,"invalid cmd name"}, {ENGINE_R_INVALID_CMD_NUMBER ,"invalid cmd number"}, +{ENGINE_R_INVALID_INIT_VALUE ,"invalid init value"}, {ENGINE_R_INVALID_STRING ,"invalid string"}, {ENGINE_R_NOT_INITIALISED ,"not initialised"}, {ENGINE_R_NOT_LOADED ,"not loaded"}, diff --git a/crypto/engine/eng_openssl.c b/crypto/engine/eng_openssl.c index 97642ae2306848831de88422b1247fd81a026997..e9d976f46bf8b5c34fe4d201899d2c64a14c0df6 100644 --- a/crypto/engine/eng_openssl.c +++ b/crypto/engine/eng_openssl.c @@ -62,11 +62,13 @@ #include "cryptlib.h" #include #include +#include /* This testing gunk is implemented (and explained) lower down. It also assumes * the application explicitly calls "ENGINE_load_openssl()" because this is no * longer automatic in ENGINE_load_builtin_engines(). */ #define TEST_ENG_OPENSSL_RC4 +#define TEST_ENG_OPENSSL_PKEY /* #define TEST_ENG_OPENSSL_RC4_OTHERS */ #define TEST_ENG_OPENSSL_RC4_P_INIT /* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */ @@ -85,6 +87,11 @@ static int openssl_digests(ENGINE *e, const EVP_MD **digest, const int **nids, int nid); #endif +#ifdef TEST_ENG_OPENSSL_PKEY +static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +#endif + /* The constants used when creating the ENGINE */ static const char *engine_openssl_id = "openssl"; static const char *engine_openssl_name = "Software engine support"; @@ -95,6 +102,7 @@ static int bind_helper(ENGINE *e) { if(!ENGINE_set_id(e, engine_openssl_id) || !ENGINE_set_name(e, engine_openssl_name) +#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS #ifndef OPENSSL_NO_RSA || !ENGINE_set_RSA(e, RSA_get_default_method()) #endif @@ -110,6 +118,10 @@ static int bind_helper(ENGINE *e) #endif #ifdef TEST_ENG_OPENSSL_SHA || !ENGINE_set_digests(e, openssl_digests) +#endif +#endif +#ifdef TEST_ENG_OPENSSL_PKEY + || !ENGINE_set_load_privkey_function(e, openssl_load_privkey) #endif ) return 0; @@ -317,3 +329,19 @@ static int openssl_digests(ENGINE *e, const EVP_MD **digest, return 1; } #endif + +#ifdef TEST_ENG_OPENSSL_PKEY +static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, void *callback_data) + { + BIO *in; + EVP_PKEY *key; + fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n", key_id); + in = BIO_new_file(key_id, "r"); + if (!in) + return NULL; + key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL); + BIO_free(in); + return key; + } +#endif diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h index 3a9ad0fe93ddc59808c8d508de58ed542994fb06..6c8b0437f854abf4335a58530ca1b784748df444 100644 --- a/crypto/engine/engine.h +++ b/crypto/engine/engine.h @@ -707,6 +707,7 @@ void ERR_load_ENGINE_strings(void); #define ENGINE_R_INVALID_ARGUMENT 143 #define ENGINE_R_INVALID_CMD_NAME 137 #define ENGINE_R_INVALID_CMD_NUMBER 138 +#define ENGINE_R_INVALID_INIT_VALUE 151 #define ENGINE_R_INVALID_STRING 150 #define ENGINE_R_NOT_INITIALISED 117 #define ENGINE_R_NOT_LOADED 112