Hi,
This patch obsoletes that which I sent on Feb 17. It is simply a port
of Geoff Thorpe's patch, submitted on July 12, 2001, to apache 2.0.48.
According to list archives, there was never a response to this patch.
Using this patch,
1. users of openssl versions prior to 0.9.8 (which has not yet been
released) can utilize dynamic engines. This means that vendors can
provide dynamic crypto engines to customers without requiring
recompilation of openssl and apache. For instance, our sample ssl.conf
contained the lines:
SSLCryptoDevice dynamic
SSLCryptoDeviceCtrl SO_PATH:/usr/local/lib/hw_ibmca.so
SSLCryptoDeviceCtrl ID:ibmca
SSLCryptoDeviceCtrl LIST_ADD:1
SSLCryptoDeviceCtrl LOAD
2. These directives can be used to send engine-specific commands to an
openssl engine. This remains useful after openssl 0.9.8 becomes
standard.
Comments are much appreciated.
thanks,
-serge
--
=======================================================
Serge Hallyn
Security Software Engineer, IBM Linux Technology Center
[EMAIL PROTECTED]
diff -Nru httpd-2.0.48-clean/modules/ssl/mod_ssl.c httpd-2.0.48-ctrl/modules/ssl/mod_ssl.c
--- httpd-2.0.48-clean/modules/ssl/mod_ssl.c 2003-03-10 22:40:43.000000000 -0800
+++ httpd-2.0.48-ctrl/modules/ssl/mod_ssl.c 2004-02-18 11:41:04.000000000 -0800
@@ -120,6 +120,9 @@
SSL_CMD_SRV(CryptoDevice, TAKE1,
"SSL external Crypto Device usage "
"(`builtin', `...')")
+ SSL_CMD_SRV(CryptoDeviceCtrl, TAKE12,
+ "SSL external Crypto Device custom control commands "
+ "(`cmd[:arg] [pre|post]')")
#endif
SSL_CMD_SRV(RandomSeed, TAKE23,
"SSL Pseudo Random Number Generator (PRNG) seeding source "
diff -Nru httpd-2.0.48-clean/modules/ssl/mod_ssl.h httpd-2.0.48-ctrl/modules/ssl/mod_ssl.h
--- httpd-2.0.48-clean/modules/ssl/mod_ssl.h 2003-09-15 18:00:06.000000000 -0700
+++ httpd-2.0.48-ctrl/modules/ssl/mod_ssl.h 2004-02-18 14:36:46.000000000 -0800
@@ -445,6 +445,7 @@
apr_hash_t *tPrivateKey;
#ifdef SSL_EXPERIMENTAL_ENGINE
char *szCryptoDevice;
+ apr_table_t *tCryptoDeviceCtrl;
#endif
struct {
void *pV1, *pV2, *pV3, *pV4, *pV5, *pV6, *pV7, *pV8, *pV9, *pV10;
@@ -559,6 +560,7 @@
const char *ssl_cmd_SSLMutex(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCryptoDevice(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLCryptoDeviceCtrl(cmd_parms *, void *, const char *, const char *);
const char *ssl_cmd_SSLRandomSeed(cmd_parms *, void *, const char *, const char *, const char *);
const char *ssl_cmd_SSLEngine(cmd_parms *, void *, int);
const char *ssl_cmd_SSLCipherSuite(cmd_parms *, void *, const char *);
diff -Nru httpd-2.0.48-clean/modules/ssl/ssl_engine_config.c httpd-2.0.48-ctrl/modules/ssl/ssl_engine_config.c
--- httpd-2.0.48-clean/modules/ssl/ssl_engine_config.c 2003-09-15 18:00:06.000000000 -0700
+++ httpd-2.0.48-ctrl/modules/ssl/ssl_engine_config.c 2004-02-18 14:36:39.000000000 -0800
@@ -109,6 +109,7 @@
mc->tPublicCert = apr_hash_make(pool);
#ifdef SSL_EXPERIMENTAL_ENGINE
mc->szCryptoDevice = NULL;
+ mc->tCryptoDeviceCtrl = apr_table_make(mc->pPool, 10);
#endif
memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys));
@@ -559,6 +560,66 @@
return NULL;
}
+
+/* Our static variables get reset between first and second pass ... so this
+ * variable is mixed in key-value strings and incremented. On the second pass,
+ * the key-values will match so will replace, rather than supplement, the table
+ * entries. (All this to prevent getting two copies of everything?!) */
+static int braindead = 0;
+
+const char *ssl_cmd_SSLCryptoDeviceCtrl(cmd_parms *cmd,
+ void *dcfg,
+ const char *arg,
+ const char *prepost)
+{
+ SSLModConfigRec *mc = myModConfig(cmd->server);
+ const char *err;
+ ENGINE *e;
+ char *colon, *value, *converted_arg, *converted_val;
+
+ if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
+ return err;
+ if ((e = ENGINE_by_id(mc->szCryptoDevice)) == NULL) {
+ err = "SSLCryptoDeviceCtrl: Must follow a valid engine";
+ goto end;
+ }
+ if (!ENGINE_ctrl(e, ENGINE_CTRL_HAS_CTRL_FUNCTION, 0, NULL, NULL)) {
+ err = "SSLCryptoDeviceCtrl: The engine has no 'ctrl' handler";
+ goto end;
+ }
+ if(prepost) {
+ if(strcmp(prepost, "pre") && strcmp(prepost, "post")) {
+ err = "SSLCryptoDeviceCtrl: Only 'pre' and 'post are valid options";
+ goto end;
+ }
+ } else
+ prepost = "pre";
+ /* Now separate out the argument into name:value (or name:'NULL' if there is
+ * no value). */
+ colon = strchr(arg, ':');
+ if(colon) {
+ *colon = '\0';
+ value = colon + 1;
+ } else
+ value = NULL;
+ if (ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FROM_NAME, 0, arg, NULL) < 0) {
+ err = "SSLCryptoDeviceCtrl: The engine doesn't recognise that command";
+ goto end;
+ }
+ converted_arg = apr_palloc(cmd->pool, strlen(arg) + 7);
+ sprintf(converted_arg, "%i,%s", braindead++, arg);
+ if(!value)
+ converted_val = prepost;
+ else {
+ converted_val = apr_palloc(cmd->pool, strlen(value) + 5);
+ sprintf(converted_val, "%s%s", prepost, value);
+ }
+ apr_table_set(mc->tCryptoDeviceCtrl, converted_arg, converted_val);
+end:
+ if(e)
+ ENGINE_free(e);
+ return err;
+ }
#endif
const char *ssl_cmd_SSLRandomSeed(cmd_parms *cmd,
diff -Nru httpd-2.0.48-clean/modules/ssl/ssl_engine_init.c httpd-2.0.48-ctrl/modules/ssl/ssl_engine_init.c
--- httpd-2.0.48-clean/modules/ssl/ssl_engine_init.c 2003-05-16 11:12:18.000000000 -0700
+++ httpd-2.0.48-ctrl/modules/ssl/ssl_engine_init.c 2004-02-18 19:47:43.000000000 -0800
@@ -350,10 +350,48 @@
* a hardware accellerator card for crypto operations.
*/
#ifdef SSL_EXPERIMENTAL_ENGINE
+struct engine_dummy {
+ ENGINE *e;
+ int ispost;
+ const char *bailed;
+};
+static int internal_ctrl_cb(void *r, const char *k, const char *v)
+{
+ struct engine_dummy *d = (struct engine_dummy *)r;
+ while (isdigit(*k) || (*k == ','))
+ k++;
+ if (strncmp(v, "post", 4) == 0) {
+ /* This key-value pair is for "post" operation */
+ if (!d->ispost)
+ return 1;
+ v += 4;
+ } else {
+ /* THis key-value pair is for "pre" operation */
+ if (d->ispost)
+ return 1;
+ v += 3;
+ }
+ if (strlen(v) == 0)
+ v = NULL;
+
+ if (!ENGINE_ctrl_cmd_string(d->e, k, v, 0)) {
+ d->bailed = k;
+ return 0;
+ }
+ return 1;
+}
+
void ssl_init_Engine(server_rec *s, apr_pool_t *p)
{
SSLModConfigRec *mc = myModConfig(s);
ENGINE *e;
+ struct engine_dummy d;
+ static int engine_initialized = 0;
+
+ if (engine_initialized) {
+ /* only init the engine once */
+ return;
+ }
if (mc->szCryptoDevice) {
if (!(e = ENGINE_by_id(mc->szCryptoDevice))) {
@@ -363,6 +401,16 @@
ssl_die();
}
+ d.e = e;
+ d.ispost = 0;
+ d.bailed = NULL;
+ apr_table_do(internal_ctrl_cb, &d, mc->tCryptoDeviceCtrl, NULL);
+ if (d.bailed) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ "Init: Failed on command '%s'", d.bailed);
+ ssl_die();
+ }
+
if (strEQ(mc->szCryptoDevice, "chil")) {
ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
}
@@ -374,8 +422,18 @@
ssl_die();
}
+ d.ispost = 1;
+ apr_table_do(internal_ctrl_cb, &d, mc->tCryptoDeviceCtrl, NULL);
+ if (d.bailed) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ "Init: Failed on command '%s'", d.bailed);
+ ssl_die();
+ }
+
ENGINE_free(e);
}
+
+ engine_initialized = 1;
}
#endif