]> granicus.if.org Git - apache/commitdiff
Introduce SSLFIPS directive to support OpenSSL FIPS_mode; permits all
authorWilliam A. Rowe Jr <wrowe@apache.org>
Mon, 22 Mar 2010 06:53:41 +0000 (06:53 +0000)
committerWilliam A. Rowe Jr <wrowe@apache.org>
Mon, 22 Mar 2010 06:53:41 +0000 (06:53 +0000)
builds of mod_ssl to use 'SSLFIPS off' for portability, but the proper
build of openssl is required for 'SSLFIPS on'.

PR: 46270
Submitted by: Dr Stephen Henson <steve openssl.org>, wrowe

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@925980 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
docs/manual/mod/mod_ssl.xml
modules/ssl/mod_ssl.c
modules/ssl/ssl_engine_config.c
modules/ssl/ssl_engine_init.c
modules/ssl/ssl_private.h
modules/ssl/ssl_toolkit_compat.h

diff --git a/CHANGES b/CHANGES
index e243a6b389fb027342461bac40af53ab7bbcc327..fa06c75b6ce80cd174a4dfa474dbb5f6a53cd1ee 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -28,6 +28,11 @@ Changes with Apache 2.3.7
      processing is completed, avoiding orphaned callback pointers.
      [Brett Gervasoni <brettg senseofsecurity.com>, Jeff Trawick]
 
+  *) 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 <steve openssl.org>, William Rowe]
+
   *) mod_proxy_http: Log the port of the remote server in various messages.
      PR 48812. [Igor Galić <i galic brainsware org>] 
 
index 7057e739b9652aa53ab31692599fbd066ce1bfdd..4374fa76c9246c372f76e6797ee44ac67db58618 100644 (file)
@@ -455,6 +455,33 @@ Within HTTP/1.1. At this time no web browsers support RFC 2817.</p>
 </usage>
 </directivesynopsis>
 
+<directivesynopsis>
+<name>SSLFIPS</name>
+<description>SSL FIPS mode Switch</description>
+<syntax>SSLFIPS on|off</syntax>
+<default>SSLFIPS off</default>
+<contextlist><context>server config</context></contextlist>
+
+<usage>
+<p>
+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.
+</p>
+<p>
+If httpd was compiled against an SSL library which did not support
+the FIPS_mode flag, <code>SSLFIPS on</code> 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.
+</p>
+</usage>
+</directivesynopsis>
+
 <directivesynopsis>
 <name>SSLProtocol</name>
 <description>Configure usable SSL protocol versions</description>
index 317cbfbf2aad7267ba50f5ff94d224a1e2d3328b..4ae3b06cfd33d07b414f0b71a6ce348a17e1d776 100644 (file)
@@ -76,6 +76,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)")
index 6c77018e9acafe8ab1715e3b79207c6f712ce222..1ba2febafcd3e4898314ca1aa9bd3409a3614feb 100644 (file)
@@ -292,6 +292,9 @@ void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
 
     cfgMerge(mc, NULL);
     cfgMerge(enabled, SSL_ENABLED_UNSET);
+#ifdef HAVE_FIPS
+    cfgMergeBool(fips);
+#endif
     cfgMergeBool(proxy_enabled);
     cfgMergeInt(session_cache_timeout);
     cfgMergeBool(cipher_server_pref);
@@ -575,6 +578,27 @@ 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)
+{
+    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    const char *err;
+
+    if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
+        return err;
+    }
+
+#ifdef HAVE_FIPS
+    if ((sc->fips != UNSET) && (sc->fips != (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)
index b73ef55df18765a176ca567de7d083a763635334..e65e2604c397df59af2952b399b2b88d586f4b37 100644 (file)
@@ -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)))
     {
@@ -231,6 +256,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
index 8d1ba8baa82d5f29b586df3552819cdeba9137b7..53bc80391aa610c2776f606ff33cbca8fd18a2d4 100644 (file)
@@ -516,6 +516,9 @@ struct SSLSrvConfigRec {
 #ifndef OPENSSL_NO_TLSEXT
     ssl_enabled_t    strict_sni_vhost_check;
 #endif
+#ifdef HAVE_FIPS
+    BOOL             fips;
+#endif
 };
 
 /**
@@ -601,6 +604,8 @@ const char *ssl_cmd_SSLOCSPOverrideResponder(cmd_parms *cmd, void *dcfg, int fla
 const char *ssl_cmd_SSLOCSPDefaultResponder(cmd_parms *cmd, void *dcfg, const char *arg);
 const char *ssl_cmd_SSLOCSPEnable(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 *);
index ec0ec856ea875df3282f35c1a1660d0f0eb7fc3a..276db45d76ccd2c7b663c30cdcf7ed935e1212a5 100644 (file)
@@ -161,6 +161,10 @@ typedef int (modssl_read_bio_cb_fn)(char*,int,int,void*);
 #define HAVE_OCSP_STAPLING
 #endif
 
+#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 */