From: Jim Jagielski
Date: Mon, 12 Jul 2010 18:47:45 +0000 (+0000)
Subject: * Introduce SSLFIPS directive to support OpenSSL FIPS_mode; permits all
X-Git-Tag: 2.2.16~23
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=07ba9ba5609b58f054fcec53f9baa00f9f8d8cf9;p=thirdparty%2Fapache%2Fhttpd.git
* Introduce SSLFIPS directive to support OpenSSL FIPS_mode; permits all
builds of mod_ssl to use 'SSLFIPS off' for portability, but the proper
build of openssl is required for 'SSLFIPS on'.
PR: 46270 [Dr Stephen Henson , William Rowe]
Trunk patch: http://svn.apache.org/viewvc?rev=925980&view=rev
http://svn.apache.org/viewvc?rev=926000&view=rev
http://svn.apache.org/viewvc?rev=926614&view=rev
http://svn.apache.org/viewvc?rev=926619&view=rev
2.2.x patch: http://people.apache.org/~wrowe/ssl-fips-2.2.patch
+1: wrowe
minfrin: Doesn't build on v2.2 until you add r926614. With r926614, +1.
wrowe: Added both of rpluem's proposed patched, 926614 and 926619
+1: drh, rjung, jim
rjung: We should add a note about the first version providing this
option in the docs page, like e.g. we did for SSLInsecureRenegotiation.
wrowe asks; you mean tag? Yes, of course.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@963430 13f79535-47bb-0310-9956-ffa450edef68
---
diff --git a/STATUS b/STATUS
index 7c9ea698ceb..fd9fcd0987d 100644
--- a/STATUS
+++ b/STATUS
@@ -86,23 +86,6 @@ RELEASE SHOWSTOPPERS:
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
[ start all new proposals below, under PATCHES PROPOSED. ]
- * Introduce SSLFIPS directive to support OpenSSL FIPS_mode; permits all
- builds of mod_ssl to use 'SSLFIPS off' for portability, but the proper
- build of openssl is required for 'SSLFIPS on'.
- PR: 46270 [Dr Stephen Henson , William Rowe]
- Trunk patch: http://svn.apache.org/viewvc?rev=925980&view=rev
- http://svn.apache.org/viewvc?rev=926000&view=rev
- http://svn.apache.org/viewvc?rev=926614&view=rev
- http://svn.apache.org/viewvc?rev=926619&view=rev
- 2.2.x patch: http://people.apache.org/~wrowe/ssl-fips-2.2.patch
- +1: wrowe
- minfrin: Doesn't build on v2.2 until you add r926614. With r926614, +1.
- wrowe: Added both of rpluem's proposed patched, 926614 and 926619
- +1: drh, rjung, jim
- rjung: We should add a note about the first version providing this
- option in the docs page, like e.g. we did for SSLInsecureRenegotiation.
- wrowe asks; you mean tag? Yes, of course.
-
*) mod_filter: enable filtering of errordocuments. PR 48377
http://svn.apache.org/viewvc?view=revision&revision=894041
+1: niq, rjung, jim
diff --git a/docs/manual/mod/mod_ssl.xml b/docs/manual/mod/mod_ssl.xml
index 1e601de66bf..d7bd9067f0e 100644
--- a/docs/manual/mod/mod_ssl.xml
+++ b/docs/manual/mod/mod_ssl.xml
@@ -501,6 +501,33 @@ Within HTTP/1.1. At this time no web browsers support RFC 2817.
+
+SSLFIPS
+SSL FIPS mode Switch
+SSLFIPS on|off
+SSLFIPS off
+server config
+
+
+
+This directive toggles the usage of the SSL library FIPS_mode flag.
+It must be set in the global server context and cannot be configured
+with conflicting settings (SSLFIPS on followed by SSLFIPS off or
+similar). The mode applies to all SSL library operations.
+
+
+If httpd was compiled against an SSL library which did not support
+the FIPS_mode flag, SSLFIPS on
will fail. Refer to the
+FIPS 140-2 Security Policy document of the SSL provider library for
+specific requirements to use mod_ssl in a FIPS 140-2 approved mode
+of operation; note that mod_ssl itself is not validated, but may be
+described as using FIPS 140-2 validated cryptographic module, when
+all components are assembled and operated under the guidelines imposed
+by the applicable Security Policy.
+
+
+
+
SSLProtocol
Configure usable SSL protocol flavors
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c
index 37c13731523..5edb1c82e6c 100644
--- a/modules/ssl/mod_ssl.c
+++ b/modules/ssl/mod_ssl.c
@@ -99,6 +99,9 @@ static const command_rec ssl_config_cmds[] = {
SSL_CMD_SRV(Engine, TAKE1,
"SSL switch for the protocol engine "
"(`on', `off')")
+ SSL_CMD_SRV(FIPS, FLAG,
+ "Enable FIPS-140 mode "
+ "(`on', `off')")
SSL_CMD_ALL(CipherSuite, TAKE1,
"Colon-delimited list of permitted SSL Ciphers "
"(`XXX:...:XXX' - see manual)")
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
index e983f1e4e04..d800bb6d36d 100644
--- a/modules/ssl/ssl_engine_config.c
+++ b/modules/ssl/ssl_engine_config.c
@@ -175,6 +175,9 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
#ifndef OPENSSL_NO_TLSEXT
sc->strict_sni_vhost_check = SSL_ENABLED_UNSET;
#endif
+#ifdef HAVE_FIPS
+ sc->fips = UNSET;
+#endif
modssl_ctx_init_proxy(sc, p);
@@ -269,6 +272,9 @@ void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
#ifndef OPENSSL_NO_TLSEXT
cfgMerge(strict_sni_vhost_check, SSL_ENABLED_UNSET);
#endif
+#ifdef HAVE_FIPS
+ cfgMergeBool(fips);
+#endif
modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy);
@@ -635,6 +641,29 @@ const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, const char *arg)
return "Argument must be On, Off, or Optional";
}
+const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag)
+{
+#ifdef HAVE_FIPS
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+#endif
+ const char *err;
+
+ if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
+ return err;
+ }
+
+#ifdef HAVE_FIPS
+ if ((sc->fips != UNSET) && (sc->fips != (BOOL)(flag ? TRUE : FALSE)))
+ return "Conflicting SSLFIPS options, cannot be both On and Off";
+ sc->fips = flag ? TRUE : FALSE;
+#else
+ if (flag)
+ return "SSLFIPS invalid, rebuild httpd and openssl compiled for FIPS";
+#endif
+
+ return NULL;
+}
+
const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
void *dcfg,
const char *arg)
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index 05d450af625..00580b84a2f 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -79,12 +79,25 @@ static int ssl_tmp_key_init_rsa(server_rec *s,
{
SSLModConfigRec *mc = myModConfig(s);
+#ifdef HAVE_FIPS
+
+ if (FIPS_mode() && bits < 1024) {
+ mc->pTmpKeys[idx] = NULL;
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ "Init: Skipping generating temporary "
+ "%d bit RSA private key in FIPS mode", bits);
+ return OK;
+ }
+
+#endif
+
if (!(mc->pTmpKeys[idx] =
RSA_generate_key(bits, RSA_F4, NULL, NULL)))
{
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
"Init: Failed to generate temporary "
"%d bit RSA private key", bits);
+ ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
return !OK;
}
@@ -96,6 +109,18 @@ static int ssl_tmp_key_init_dh(server_rec *s,
{
SSLModConfigRec *mc = myModConfig(s);
+#ifdef HAVE_FIPS
+
+ if (FIPS_mode() && bits < 1024) {
+ mc->pTmpKeys[idx] = NULL;
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ "Init: Skipping generating temporary "
+ "%d bit DH parameters in FIPS mode", bits);
+ return OK;
+ }
+
+#endif
+
if (!(mc->pTmpKeys[idx] =
ssl_dh_GetTmpParam(bits)))
{
@@ -208,6 +233,11 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
sc->server->pphrase_dialog_type = SSL_PPTYPE_BUILTIN;
}
+#ifdef HAVE_FIPS
+ if (sc->fips == UNSET) {
+ sc->fips = FALSE;
+ }
+#endif
}
#if APR_HAS_THREADS
@@ -231,6 +261,26 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
*/
ssl_rand_seed(base_server, ptemp, SSL_RSCTX_STARTUP, "Init: ");
+#ifdef HAVE_FIPS
+ if(sc->fips) {
+ if (!FIPS_mode()) {
+ if (FIPS_mode_set(1)) {
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
+ "Operating in SSL FIPS mode");
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "FIPS mode failed");
+ ssl_log_ssl_error(APLOG_MARK, APLOG_EMERG, s);
+ ssl_die();
+ }
+ }
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
+ "SSL FIPS mode disabled");
+ }
+#endif
+
/*
* read server private keys/public certs into memory.
* decrypting any encrypted keys via configured SSLPassPhraseDialogs
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
index 0613f0d213a..af6d0f7259b 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -479,6 +479,9 @@ struct SSLSrvConfigRec {
#ifndef OPENSSL_NO_TLSEXT
ssl_enabled_t strict_sni_vhost_check;
#endif
+#ifdef HAVE_FIPS
+ BOOL fips;
+#endif
};
/**
@@ -562,6 +565,8 @@ const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *, void *, const c
const char *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag);
const char *ssl_cmd_SSLProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag);
+const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag);
+
/** module initialization */
int ssl_init_Module(apr_pool_t *, apr_pool_t *, apr_pool_t *, server_rec *);
void ssl_init_Engine(server_rec *, apr_pool_t *);
diff --git a/modules/ssl/ssl_toolkit_compat.h b/modules/ssl/ssl_toolkit_compat.h
index a841eccda7b..369516b2d51 100644
--- a/modules/ssl/ssl_toolkit_compat.h
+++ b/modules/ssl/ssl_toolkit_compat.h
@@ -141,6 +141,10 @@ typedef int (modssl_read_bio_cb_fn)(char*,int,int,void*);
#define HAVE_SSL_X509V3_EXT_d2i
+#if (OPENSSL_VERSION_NUMBER >= 0x009080a0) && defined(OPENSSL_FIPS)
+#define HAVE_FIPS
+#endif
+
#ifndef PEM_F_DEF_CALLBACK
#ifdef PEM_F_PEM_DEF_CALLBACK
/** In OpenSSL 0.9.8 PEM_F_DEF_CALLBACK was renamed */