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

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