Blame SOURCES/openssl-1.0.2a-fips-ctor.patch

96a864
diff -up openssl-1.0.2a/crypto/fips/fips.c.fips-ctor openssl-1.0.2a/crypto/fips/fips.c
96a864
--- openssl-1.0.2a/crypto/fips/fips.c.fips-ctor	2015-04-21 17:42:18.702765856 +0200
96a864
+++ openssl-1.0.2a/crypto/fips/fips.c	2015-04-21 17:42:18.742766794 +0200
96a864
@@ -60,6 +60,8 @@
96a864
 #include <dlfcn.h>
96a864
 #include <stdio.h>
96a864
 #include <stdlib.h>
96a864
+#include <unistd.h>
96a864
+#include <errno.h>
96a864
 #include "fips_locl.h"
96a864
 
96a864
 #ifdef OPENSSL_FIPS
96a864
@@ -201,7 +203,9 @@ static char *bin2hex(void *buf, size_t l
96a864
 }
96a864
 
96a864
 # define HMAC_PREFIX "."
96a864
-# define HMAC_SUFFIX ".hmac"
96a864
+# ifndef HMAC_SUFFIX
96a864
+#  define HMAC_SUFFIX ".hmac"
96a864
+# endif
96a864
 # define READ_BUFFER_LENGTH 16384
96a864
 
96a864
 static char *make_hmac_path(const char *origpath)
96a864
@@ -279,20 +283,14 @@ static int compute_file_hmac(const char
96a864
     return rv;
96a864
 }
96a864
 
96a864
-static int FIPSCHECK_verify(const char *libname, const char *symbolname)
96a864
+static int FIPSCHECK_verify(const char *path)
96a864
 {
96a864
-    char path[PATH_MAX + 1];
96a864
-    int rv;
96a864
+    int rv = 0;
96a864
     FILE *hf;
96a864
     char *hmacpath, *p;
96a864
     char *hmac = NULL;
96a864
     size_t n;
96a864
 
96a864
-    rv = get_library_path(libname, symbolname, path, sizeof(path));
96a864
-
96a864
-    if (rv < 0)
96a864
-        return 0;
96a864
-
96a864
     hmacpath = make_hmac_path(path);
96a864
     if (hmacpath == NULL)
96a864
         return 0;
96a864
@@ -343,6 +341,51 @@ static int FIPSCHECK_verify(const char *
96a864
     return 1;
96a864
 }
96a864
 
96a864
+static int verify_checksums(void)
96a864
+{
96a864
+    int rv;
96a864
+    char path[PATH_MAX + 1];
96a864
+    char *p;
96a864
+
96a864
+    /* we need to avoid dlopening libssl, assume both libcrypto and libssl
96a864
+       are in the same directory */
96a864
+
96a864
+    rv = get_library_path("libcrypto.so." SHLIB_VERSION_NUMBER,
96a864
+                          "FIPS_mode_set", path, sizeof(path));
96a864
+    if (rv < 0)
96a864
+        return 0;
96a864
+
96a864
+    rv = FIPSCHECK_verify(path);
96a864
+    if (!rv)
96a864
+        return 0;
96a864
+
96a864
+    /* replace libcrypto with libssl */
96a864
+    while ((p = strstr(path, "libcrypto.so")) != NULL) {
96a864
+        p = stpcpy(p, "libssl");
96a864
+        memmove(p, p + 3, strlen(p + 2));
96a864
+    }
96a864
+
96a864
+    rv = FIPSCHECK_verify(path);
96a864
+    if (!rv)
96a864
+        return 0;
96a864
+    return 1;
96a864
+}
96a864
+
96a864
+# ifndef FIPS_MODULE_PATH
96a864
+#  define FIPS_MODULE_PATH "/etc/system-fips"
96a864
+# endif
96a864
+
96a864
+int FIPS_module_installed(void)
96a864
+{
96a864
+    int rv;
96a864
+    rv = access(FIPS_MODULE_PATH, F_OK);
96a864
+    if (rv < 0 && errno != ENOENT)
96a864
+        rv = 0;
96a864
+
96a864
+    /* Installed == true */
96a864
+    return !rv;
96a864
+}
96a864
+
96a864
 int FIPS_module_mode_set(int onoff, const char *auth)
96a864
 {
96a864
     int ret = 0;
96a864
@@ -380,17 +423,7 @@ int FIPS_module_mode_set(int onoff, cons
96a864
         }
96a864
 # endif
96a864
 
96a864
-        if (!FIPSCHECK_verify
96a864
-            ("libcrypto.so." SHLIB_VERSION_NUMBER, "FIPS_mode_set")) {
96a864
-            FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,
96a864
-                    FIPS_R_FINGERPRINT_DOES_NOT_MATCH);
96a864
-            fips_selftest_fail = 1;
96a864
-            ret = 0;
96a864
-            goto end;
96a864
-        }
96a864
-
96a864
-        if (!FIPSCHECK_verify
96a864
-            ("libssl.so." SHLIB_VERSION_NUMBER, "SSL_CTX_new")) {
96a864
+        if (!verify_checksums()) {
96a864
             FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,
96a864
                     FIPS_R_FINGERPRINT_DOES_NOT_MATCH);
96a864
             fips_selftest_fail = 1;
96a864
diff -up openssl-1.0.2a/crypto/fips/fips.h.fips-ctor openssl-1.0.2a/crypto/fips/fips.h
96a864
--- openssl-1.0.2a/crypto/fips/fips.h.fips-ctor	2015-04-21 17:42:18.739766724 +0200
96a864
+++ openssl-1.0.2a/crypto/fips/fips.h	2015-04-21 17:42:18.743766818 +0200
96a864
@@ -74,6 +74,7 @@ extern "C" {
96a864
 
96a864
     int FIPS_module_mode_set(int onoff, const char *auth);
96a864
     int FIPS_module_mode(void);
96a864
+    int FIPS_module_installed(void);
96a864
     const void *FIPS_rand_check(void);
96a864
     int FIPS_selftest(void);
96a864
     int FIPS_selftest_failed(void);
96a864
diff -up openssl-1.0.2a/crypto/o_init.c.fips-ctor openssl-1.0.2a/crypto/o_init.c
96a864
--- openssl-1.0.2a/crypto/o_init.c.fips-ctor	2015-04-21 17:42:18.732766559 +0200
96a864
+++ openssl-1.0.2a/crypto/o_init.c	2015-04-21 17:45:02.662613173 +0200
96a864
@@ -74,6 +74,9 @@ static void init_fips_mode(void)
96a864
     char buf[2] = "0";
96a864
     int fd;
96a864
 
96a864
+    /* Ensure the selftests always run */
96a864
+    FIPS_mode_set(1);
96a864
+
96a864
     if (secure_getenv("OPENSSL_FORCE_FIPS_MODE") != NULL) {
96a864
         buf[0] = '1';
96a864
     } else if ((fd = open(FIPS_MODE_SWITCH_FILE, O_RDONLY)) >= 0) {
96a864
@@ -85,8 +88,12 @@ static void init_fips_mode(void)
96a864
      * otherwise..
96a864
      */
96a864
 
96a864
-    if (buf[0] == '1') {
96a864
-        FIPS_mode_set(1);
96a864
+    if (buf[0] != '1') {
96a864
+        /* drop down to non-FIPS mode if it is not requested */
96a864
+        FIPS_mode_set(0);
96a864
+    } else {
96a864
+        /* abort if selftest failed */
96a864
+        FIPS_selftest_check();
96a864
     }
96a864
 }
96a864
 #endif
96a864
@@ -96,13 +103,16 @@ static void init_fips_mode(void)
96a864
  * sets FIPS callbacks
96a864
  */
96a864
 
96a864
-void OPENSSL_init_library(void)
96a864
+void __attribute__ ((constructor)) OPENSSL_init_library(void)
96a864
 {
96a864
     static int done = 0;
96a864
     if (done)
96a864
         return;
96a864
     done = 1;
96a864
 #ifdef OPENSSL_FIPS
96a864
+    if (!FIPS_module_installed()) {
96a864
+        return;
96a864
+    }
96a864
     RAND_init_fips();
96a864
     init_fips_mode();
96a864
     if (!FIPS_mode()) {