Hi all,

Please find attached a patch to add support for enabling FIPS-140 mode in Monit.

This requires an OpenSSL installation that supports FIPS-140 (see
http://openssl.org/docs/fips/ for details).

The patch does the following:

1. Add a global "set fips" directive to enable FIPS-140 mode.
2. Force using TLSv1 instead of SSLv23 (as per FIPS-140 requirements)
3. Disable the certmd5 option when in FIPS mode since md5 is not
available when in FIPS-140 mode.

Regards,
Lior Okman
Index: monitor.h
===================================================================
--- monitor.h	(revision 205)
+++ monitor.h	(working copy)
@@ -864,6 +864,9 @@
   } MailFormat;
                                           
   pthread_mutex_t mutex;    /**< Mutex used for service data synchronization */
+#ifdef OPENSSL_FIPS
+  int fipsEnabled;                /** TRUE if monit should use FIPS-140 mode */
+#endif
 };
 
 
Index: ssl.c
===================================================================
--- ssl.c	(revision 205)
+++ ssl.c	(working copy)
@@ -337,8 +337,18 @@
     start_ssl();
 
   ssl_server = new_ssl_server_connection(pemfile, clientpemfile);
-  
-  if(!(ssl_server->method= SSLv23_server_method())) {
+  SSL_METHOD *server_method = NULL;
+#ifdef OPENSSL_FIPS
+  if (FIPS_mode()) {
+	  server_method = TLSv1_server_method();
+  }
+  else {
+	  server_method = SSLv23_server_method();
+  }
+#else
+  server_method = SSLv23_server_method();
+#endif
+  if(!(ssl_server->method= server_method)) {
     LogError("%s: Cannot initialize the SSL method -- %s\n", prog, SSLERROR);
     goto sslerror;
   }
@@ -667,15 +677,41 @@
   switch (sslversion) {
 
   case SSL_VERSION_AUTO:
-    ssl->method = SSLv23_client_method();
+#ifdef OPENSSL_FIPS
+	  if (FIPS_mode()) {
+	    ssl->method = TLSv1_client_method();
+	  } else {
+#endif
+		ssl->method = SSLv23_client_method();
+#ifdef OPENSSL_FIPS
+	  }
+#endif
     break;
 
   case SSL_VERSION_SSLV2:
-    ssl->method = SSLv2_client_method();
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) {
+	  LogError("SSLv2 is not allowed in FIPS mode - use TLSv1");
+	  goto sslerror;
+	} else {
+#endif
+	  ssl->method = SSLv2_client_method();
+#ifdef OPENSSL_FIPS
+	}
+#endif
     break;
 
   case SSL_VERSION_SSLV3:
-    ssl->method = SSLv3_client_method();
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) {
+	  LogError("SSLv3 is not allowed in FIPS mode - use TLSv1");
+	  goto sslerror;
+	} else {
+#endif
+      ssl->method = SSLv3_client_method();
+#ifdef OPENSSL_FIPS
+	}
+#endif
     break;
 
   case SSL_VERSION_TLS:
@@ -1019,11 +1055,17 @@
   if(!(ssl->cert = SSL_get_peer_certificate(ssl->handler)))
     return FALSE;
 
-  ssl->cert_issuer= X509_NAME_oneline (X509_get_issuer_name(ssl->cert), 0, 0);
-  ssl->cert_subject= X509_NAME_oneline (X509_get_subject_name(ssl->cert), 0, 0);
-  X509_digest(ssl->cert, EVP_md5(), md5, &ssl->cert_md5_len);
-  ssl->cert_md5= (unsigned char *)xstrdup((char *)md5);
-
+#ifdef OPENSSL_FIPS
+  if (!FIPS_mode()) {
+    /* In FIPS-140 mode, MD5 is unavailable. */
+#endif
+    ssl->cert_issuer= X509_NAME_oneline (X509_get_issuer_name(ssl->cert), 0, 0);
+    ssl->cert_subject= X509_NAME_oneline (X509_get_subject_name(ssl->cert), 0, 0);
+    X509_digest(ssl->cert, EVP_md5(), md5, &ssl->cert_md5_len);
+    ssl->cert_md5= (unsigned char *)xstrdup((char *)md5);
+#ifdef OPENSSL_FIPS
+  }
+#endif
   return TRUE;
 
 }
@@ -1052,6 +1094,18 @@
 
 }
 
+#ifdef OPENSSL_FIPS
+/**
+ * Enable FIPS mode, if it isn't enabled yet.
+ */
+void enable_fips_mode()
+{
+	if (!FIPS_mode()) {
+		ASSERT(FIPS_mode_set(1));
+		LogInfo("FIPS-140 mode is enabled\n");
+	}
+}
+#endif
 
 /**
  * Start SSL support library. It has to be run before the SSL support
@@ -1061,6 +1115,11 @@
 static int start_ssl() {
 
   if(! ssl_initialized) {
+#ifdef OPENSSL_FIPS
+	if (Run.fipsEnabled) {
+		enable_fips_mode();
+	}
+#endif
     int i;
     int locks = CRYPTO_num_locks();
 
Index: l.l
===================================================================
--- l.l	(revision 205)
+++ l.l	(working copy)
@@ -305,6 +305,7 @@
 credentials       { return CREDENTIALS; }
 register          { return REGISTER; }
 fsflag(s)?        { return FSFLAG; }
+fips              { return FIPS; }
 {byte}            { return BYTE; }
 {kilobyte}        { return KILOBYTE; }
 {megabyte}        { return MEGABYTE; }
Index: ssl.h
===================================================================
--- ssl.h	(revision 205)
+++ ssl.h	(working copy)
@@ -38,7 +38,10 @@
 #include <openssl/pem.h>
 #include <openssl/ssl.h>
 #include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
 #endif
+#endif
 
 #define SSL_VERSION_AUTO       0
 #define SSL_VERSION_SSLV2      1
@@ -102,6 +105,9 @@
 ssl_connection        *new_ssl_connection(char *, int);
 ssl_connection        *insert_accepted_ssl_socket(ssl_server_connection *);
 ssl_server_connection *init_ssl_server(char *, char *);
+#ifdef OPENSSL_FIPS
+void                   enable_fips_mode();
+#endif
 
 
 #else
Index: p.y
===================================================================
--- p.y	(revision 205)
+++ p.y	(working copy)
@@ -303,6 +303,7 @@
 %token <url> URLOBJECT
 %token <string> TARGET
 %token <number> MAXFORWARD
+%token FIPS
 
 %left GREATER LESS EQUAL NOTEQUAL
 
@@ -329,6 +330,7 @@
                 | setstatefile
                 | setexpectbuffer
                 | setinit
+                | setfips
                 | checkproc optproclist
                 | checkfile optfilelist
                 | checkfilesys optfilesyslist
@@ -516,6 +518,13 @@
                   }
                 ;
 
+setfips         : SET FIPS {
+                  #ifdef OPENSSL_FIPS
+                    Run.fipsEnabled = TRUE;
+                  #endif
+                  }
+                ;
+
 setlog          : SET LOGFILE PATH   {
                    if (!Run.logfile || ihp.logfile) {
                      ihp.logfile = TRUE;
@@ -1896,6 +1905,9 @@
   Run.localhostname       = xstrdup(localhost);
   depend_list             = NULL;
   Run.handler_init        = TRUE;
+#ifdef OPENSSL_FIPS  
+  Run.fipsEnabled         = FALSE;
+#endif
   for (i = 0; i <= HANDLER_MAX; i++)
     Run.handler_queue[i] = 0;
   /* 
_______________________________________________
monit-dev mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/monit-dev

Reply via email to