mturk 2005/06/01 08:20:14 Modified: jni/native/include ssl_private.h jni/native/src sslcontext.c sslutils.c Log: Handle the Temporary RSA Keys and DH Params. Revision Changes Path 1.9 +15 -2 jakarta-tomcat-connectors/jni/native/include/ssl_private.h Index: ssl_private.h =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jni/native/include/ssl_private.h,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- ssl_private.h 1 Jun 2005 10:45:02 -0000 1.8 +++ ssl_private.h 1 Jun 2005 15:20:14 -0000 1.9 @@ -85,6 +85,7 @@ #define SSL_BIO_FLAG_RDONLY (1<<0) #define SSL_BIO_FLAG_CALLBACK (1<<1) +#define SSL_DEFAULT_CACHE_SIZE (256) /* public cert/private key */ typedef struct { @@ -138,11 +139,18 @@ /* for client or downstream server authentication */ int verify_depth; int verify_mode; - + void *temp_keys[SSL_TMP_KEY_MAX]; }; typedef struct tcn_ssl_ctxt tcn_ssl_ctxt_t; +struct tcn_ssl_conn { + tcn_ssl_ctxt_t *ctx; + SSL *ssl; +}; + +typedef struct tcn_ssl_conn tcn_ssl_conn_t; + /* * Additional Functions */ @@ -152,5 +160,10 @@ int SSL_password_prompt(tcn_ssl_ctxt_t *, char *, int); void SSL_BIO_close(BIO *); void SSL_BIO_doref(BIO *); +DH *SSL_dh_get_tmp_param(int); +DH *SSL_dh_get_param_from_file(const char *); +RSA *SSL_callback_tmp_RSA(SSL *, int, int); +DH *SSL_callback_tmp_DH(SSL *, int, int); + #endif /* SSL_PRIVATE_H */ 1.14 +55 -1 jakarta-tomcat-connectors/jni/native/src/sslcontext.c Index: sslcontext.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jni/native/src/sslcontext.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- sslcontext.c 1 Jun 2005 12:36:24 -0000 1.13 +++ sslcontext.c 1 Jun 2005 15:20:14 -0000 1.14 @@ -30,6 +30,53 @@ #ifdef HAVE_OPENSSL #include "ssl_private.h" +/* + * Handle the Temporary RSA Keys and DH Params + */ + +#define SSL_TMP_KEY_FREE(ctx, type, idx) \ + if (ctx->temp_keys[idx]) { \ + type##_free((type *)ctx->temp_keys[idx]); \ + ctx->temp_keys[idx] = NULL; \ + } + +#define SSL_TMP_KEYS_FREE(ctx, type) \ + SSL_TMP_KEY_FREE(ctx, type, SSL_TMP_KEY_##type##_512); \ + SSL_TMP_KEY_FREE(ctx, type, SSL_TMP_KEY_##type##_1024) + +static void ssl_tmp_keys_free(tcn_ssl_ctxt_t *ctx) +{ + + SSL_TMP_KEYS_FREE(ctx, RSA); + SSL_TMP_KEYS_FREE(ctx, DH); +} + +static int ssl_tmp_key_init_rsa(tcn_ssl_ctxt_t *ctx, + int bits, int idx) +{ + if (!(ctx->temp_keys[idx] = + RSA_generate_key(bits, RSA_F4, NULL, NULL))) { + BIO_printf(ctx->bio_os, "[ERROR] " + "Init: Failed to generate temporary " + "%d bit RSA private key", bits); + return 0; + } + return 1; +} + +static int ssl_tmp_key_init_dh(tcn_ssl_ctxt_t *ctx, + int bits, int idx) +{ + if (!(ctx->temp_keys[idx] = + SSL_dh_get_tmp_param(bits))) { + BIO_printf(ctx->bio_os, "[ERROR] " + "Init: Failed to generate temporary " + "%d bit DH parameters", bits); + return 0; + } + return 1; +} + static apr_status_t ssl_context_cleanup(void *data) { tcn_ssl_ctxt_t *c = (tcn_ssl_ctxt_t *)data; @@ -128,6 +175,11 @@ */ SSL_CTX_set_options(c->ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); #endif + SSL_CTX_sess_set_cache_size(c->ctx, SSL_DEFAULT_CACHE_SIZE); + + SSL_CTX_set_tmp_rsa_callback(c->ctx, SSL_callback_tmp_RSA); + SSL_CTX_set_tmp_dh_callback(c->ctx, SSL_callback_tmp_DH); + /* * Let us cleanup the ssl context when the pool is destroyed */ @@ -200,6 +252,8 @@ */ SSL_CTX_set_options(c->ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); #endif + + SSL_CTX_sess_set_cache_size(c->ctx, SSL_DEFAULT_CACHE_SIZE); /* * Let us cleanup the ssl context when the pool is destroyed */ 1.8 +203 -1 jakarta-tomcat-connectors/jni/native/src/sslutils.c Index: sslutils.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jni/native/src/sslutils.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- sslutils.c 1 Jun 2005 11:22:16 -0000 1.7 +++ sslutils.c 1 Jun 2005 15:20:14 -0000 1.8 @@ -149,6 +149,208 @@ return rv; } + +/* ----BEGIN GENERATED SECTION-------- */ + +/* +** Diffie-Hellman-Parameters: (512 bit) +** prime: +** 00:d4:bc:d5:24:06:f6:9b:35:99:4b:88:de:5d:b8: +** 96:82:c8:15:7f:62:d8:f3:36:33:ee:57:72:f1:1f: +** 05:ab:22:d6:b5:14:5b:9f:24:1e:5a:cc:31:ff:09: +** 0a:4b:c7:11:48:97:6f:76:79:50:94:e7:1e:79:03: +** 52:9f:5a:82:4b +** generator: 2 (0x2) +** Diffie-Hellman-Parameters: (1024 bit) +** prime: +** 00:e6:96:9d:3d:49:5b:e3:2c:7c:f1:80:c3:bd:d4: +** 79:8e:91:b7:81:82:51:bb:05:5e:2a:20:64:90:4a: +** 79:a7:70:fa:15:a2:59:cb:d5:23:a6:a6:ef:09:c4: +** 30:48:d5:a2:2f:97:1f:3c:20:12:9b:48:00:0e:6e: +** dd:06:1c:bc:05:3e:37:1d:79:4e:53:27:df:61:1e: +** bb:be:1b:ac:9b:5c:60:44:cf:02:3d:76:e0:5e:ea: +** 9b:ad:99:1b:13:a6:3c:97:4e:9e:f1:83:9e:b5:db: +** 12:51:36:f7:26:2e:56:a8:87:15:38:df:d8:23:c6: +** 50:50:85:e2:1f:0d:d5:c8:6b +** generator: 2 (0x2) +*/ + +static unsigned char dh512_p[] = +{ + 0xD4, 0xBC, 0xD5, 0x24, 0x06, 0xF6, 0x9B, 0x35, 0x99, 0x4B, 0x88, 0xDE, + 0x5D, 0xB8, 0x96, 0x82, 0xC8, 0x15, 0x7F, 0x62, 0xD8, 0xF3, 0x36, 0x33, + 0xEE, 0x57, 0x72, 0xF1, 0x1F, 0x05, 0xAB, 0x22, 0xD6, 0xB5, 0x14, 0x5B, + 0x9F, 0x24, 0x1E, 0x5A, 0xCC, 0x31, 0xFF, 0x09, 0x0A, 0x4B, 0xC7, 0x11, + 0x48, 0x97, 0x6F, 0x76, 0x79, 0x50, 0x94, 0xE7, 0x1E, 0x79, 0x03, 0x52, + 0x9F, 0x5A, 0x82, 0x4B, +}; +static unsigned char dh512_g[] = +{ + 0x02, +}; + +static DH *ssl_dh_configure(unsigned char *p, int plen, + unsigned char *g, int glen) +{ + DH *dh; + + if (!(dh = DH_new())) { + return NULL; + } + +#if defined(OPENSSL_VERSION_NUMBER) || (SSLC_VERSION_NUMBER < 0x2000) + dh->p = BN_bin2bn(p, plen, NULL); + dh->g = BN_bin2bn(g, glen, NULL); + if (!(dh->p && dh->g)) { + DH_free(dh); + return NULL; + } +#else + R_EITEMS_add(dh->data, PK_TYPE_DH, PK_DH_P, 0, p, plen, R_EITEMS_PF_COPY); + R_EITEMS_add(dh->data, PK_TYPE_DH, PK_DH_G, 0, g, glen, R_EITEMS_PF_COPY); +#endif + + return dh; +} + +static DH *get_dh512(void) +{ + return ssl_dh_configure(dh512_p, sizeof(dh512_p), + dh512_g, sizeof(dh512_g)); +} + +static unsigned char dh1024_p[] = +{ + 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3, + 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E, + 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59, + 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2, + 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD, + 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF, + 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02, + 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C, + 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7, + 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50, + 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B, +}; +static unsigned char dh1024_g[] = +{ + 0x02, +}; + +static DH *get_dh1024(void) +{ + return ssl_dh_configure(dh1024_p, sizeof(dh1024_p), + dh1024_g, sizeof(dh1024_g)); +} +/* ----END GENERATED SECTION---------- */ + +DH *SSL_dh_get_tmp_param(int nKeyLen) +{ + DH *dh; + + if (nKeyLen == 512) + dh = get_dh512(); + else if (nKeyLen == 1024) + dh = get_dh1024(); + else + dh = get_dh1024(); + return dh; +} + +DH *SSL_dh_get_param_from_file(const char *file) +{ + DH *dh = NULL; + BIO *bio; + + if ((bio = BIO_new_file(file, "r")) == NULL) + return NULL; + dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + BIO_free(bio); + return dh; +} + +/* + * Handle out temporary RSA private keys on demand + * + * The background of this as the TLSv1 standard explains it: + * + * | D.1. Temporary RSA keys + * | + * | US Export restrictions limit RSA keys used for encryption to 512 + * | bits, but do not place any limit on lengths of RSA keys used for + * | signing operations. Certificates often need to be larger than 512 + * | bits, since 512-bit RSA keys are not secure enough for high-value + * | transactions or for applications requiring long-term security. Some + * | certificates are also designated signing-only, in which case they + * | cannot be used for key exchange. + * | + * | When the public key in the certificate cannot be used for encryption, + * | the server signs a temporary RSA key, which is then exchanged. In + * | exportable applications, the temporary RSA key should be the maximum + * | allowable length (i.e., 512 bits). Because 512-bit RSA keys are + * | relatively insecure, they should be changed often. For typical + * | electronic commerce applications, it is suggested that keys be + * | changed daily or every 500 transactions, and more often if possible. + * | Note that while it is acceptable to use the same temporary key for + * | multiple transactions, it must be signed each time it is used. + * | + * | RSA key generation is a time-consuming process. In many cases, a + * | low-priority process can be assigned the task of key generation. + * | Whenever a new key is completed, the existing temporary key can be + * | replaced with the new one. + * + * XXX: base on comment above, if thread support is enabled, + * we should spawn a low-priority thread to generate new keys + * on the fly. + * + * So we generated 512 and 1024 bit temporary keys on startup + * which we now just hand out on demand.... + */ + +RSA *SSL_callback_tmp_RSA(SSL *ssl, int export, int keylen) +{ + tcn_ssl_conn_t *conn = (tcn_ssl_conn_t *)SSL_get_app_data(ssl); + int idx; + + /* doesn't matter if export flag is on, + * we won't be asked for keylen > 512 in that case. + * if we are asked for a keylen > 1024, it is too expensive + * to generate on the fly. + * XXX: any reason not to generate 2048 bit keys at startup? + */ + + switch (keylen) { + case 512: + idx = SSL_TMP_KEY_RSA_512; + break; + case 1024: + default: + idx = SSL_TMP_KEY_RSA_1024; + break; + } + return (RSA *)conn->ctx->temp_keys[idx]; +} + +/* + * Hand out the already generated DH parameters... + */ +DH *SSL_callback_tmp_DH(SSL *ssl, int export, int keylen) +{ + tcn_ssl_conn_t *conn = (tcn_ssl_conn_t *)SSL_get_app_data(ssl); + int idx; + switch (keylen) { + case 512: + idx = SSL_TMP_KEY_DH_512; + break; + case 1024: + default: + idx = SSL_TMP_KEY_DH_1024; + break; + } + return (DH *)conn->ctx->temp_keys[idx]; +} + #else /* OpenSSL is not supported * If someday we make OpenSSL optional
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]