Make an explicit check during certificate validation to see that the
[oweals/openssl.git] / crypto / cryptlib.c
index 2924def2bb0840899d477dff44d12393f36fbc12..b8e700ce526f15ae8fa06724f8e0ed1cc3b21292 100644 (file)
@@ -105,7 +105,9 @@ static const char* lock_names[CRYPTO_NUM_LOCKS] =
        "engine",
        "ui",
        "hwcrhk",               /* This is a HACK which will disappear in 0.9.8 */
-#if CRYPTO_NUM_LOCKS != 33
+       "fips",
+       "fips2",
+#if CRYPTO_NUM_LOCKS != 35
 # error "Inconsistency between crypto.h and cryptlib.c"
 #endif
        };
@@ -512,3 +514,122 @@ void OpenSSLDie(const char *file,int line,const char *assertion)
                file,line,assertion);
        abort();
        }
+
+#ifdef OPENSSL_FIPS
+static int fips_started = 0;
+static int fips_mode = 0;
+static void *fips_rand_check = 0;
+static unsigned long fips_thread = 0;
+
+void fips_set_started(void)
+       {
+       fips_started = 1;
+       }
+
+int fips_is_started(void)
+       {
+       return fips_started;
+       }
+
+int fips_is_owning_thread(void)
+       {
+       int ret = 0;
+
+       if (fips_is_started())
+               {
+               CRYPTO_r_lock(CRYPTO_LOCK_FIPS2);
+               if (fips_thread != 0 && fips_thread == CRYPTO_thread_id())
+                       ret = 1;
+               CRYPTO_r_unlock(CRYPTO_LOCK_FIPS2);
+               }
+       return ret;
+       }
+
+int fips_set_owning_thread(void)
+       {
+       int ret = 0;
+
+       if (fips_is_started())
+               {
+               CRYPTO_w_lock(CRYPTO_LOCK_FIPS2);
+               if (fips_thread == 0)
+                       {
+                       fips_thread = CRYPTO_thread_id();
+                       ret = 1;
+                       }
+               CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2);
+               }
+       return ret;
+       }
+
+int fips_clear_owning_thread(void)
+       {
+       int ret = 0;
+
+       if (fips_is_started())
+               {
+               CRYPTO_w_lock(CRYPTO_LOCK_FIPS2);
+               if (fips_thread == CRYPTO_thread_id())
+                       {
+                       fips_thread = 0;
+                       ret = 1;
+                       }
+               CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2);
+               }
+       return ret;
+       }
+
+void fips_set_mode(int onoff)
+       {
+       int owning_thread = fips_is_owning_thread();
+
+       if (fips_is_started())
+               {
+               if (!owning_thread) CRYPTO_w_lock(CRYPTO_LOCK_FIPS);
+               fips_mode = onoff;
+               if (!owning_thread) CRYPTO_w_unlock(CRYPTO_LOCK_FIPS);
+               }
+       }
+
+void fips_set_rand_check(void *rand_check)
+       {
+       int owning_thread = fips_is_owning_thread();
+
+       if (fips_is_started())
+               {
+               if (!owning_thread) CRYPTO_w_lock(CRYPTO_LOCK_FIPS);
+               fips_rand_check = rand_check;
+               if (!owning_thread) CRYPTO_w_unlock(CRYPTO_LOCK_FIPS);
+               }
+       }
+
+int FIPS_mode(void)
+       {
+       int ret = 0;
+       int owning_thread = fips_is_owning_thread();
+
+       if (fips_is_started())
+               {
+               if (!owning_thread) CRYPTO_r_lock(CRYPTO_LOCK_FIPS);
+               ret = fips_mode;
+               if (!owning_thread) CRYPTO_r_unlock(CRYPTO_LOCK_FIPS);
+               }
+       return ret;
+       }
+
+void *FIPS_rand_check(void)
+       {
+       void *ret = 0;
+       int owning_thread = fips_is_owning_thread();
+
+       if (fips_is_started())
+               {
+               if (!owning_thread) CRYPTO_r_lock(CRYPTO_LOCK_FIPS);
+               ret = fips_rand_check;
+               if (!owning_thread) CRYPTO_r_unlock(CRYPTO_LOCK_FIPS);
+               }
+       return ret;
+       }
+
+#endif /* OPENSSL_FIPS */
+