Remove remaining calls to the old lock functions.
|SSL_CTX| and |X509_STORE| have grown their own locks. Several static
locks have been added to hack around not being able to use a
|CRYPTO_once_t| in public headers. Lastly, support for calling
|SSL_CTX_set_generate_session_id| concurrently with active connections
has been removed. No other property of an |SSL_CTX| works like that.
Change-Id: Iff5fe3ee3fdd6ea9c9daee96f850b107ad8a6bca
Reviewed-on: https://boringssl-review.googlesource.com/4775
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/x509v3/pcy_cache.c b/crypto/x509v3/pcy_cache.c
index 5d59c00..08f20aa 100644
--- a/crypto/x509v3/pcy_cache.c
+++ b/crypto/x509v3/pcy_cache.c
@@ -60,6 +60,7 @@
#include <openssl/x509v3.h>
#include "pcy_int.h"
+#include "../internal.h"
static int policy_data_cmp(const X509_POLICY_DATA **a,
@@ -243,18 +244,30 @@
OPENSSL_free(cache);
}
+/* g_x509_policy_cache_lock is used to protect against concurrent calls to
+ * |policy_cache_new|. Ideally this would be done with a |CRYPTO_once_t|
+ * in the |X509| structure, but |CRYPTO_once_t| isn't public. */
+static struct CRYPTO_STATIC_MUTEX g_x509_policy_cache_lock =
+ CRYPTO_STATIC_MUTEX_INIT;
+
const X509_POLICY_CACHE *policy_cache_set(X509 *x)
{
+ X509_POLICY_CACHE *cache;
+ CRYPTO_STATIC_MUTEX_lock_read(&g_x509_policy_cache_lock);
+ cache = x->policy_cache;
+ CRYPTO_STATIC_MUTEX_unlock(&g_x509_policy_cache_lock);
+
+ if (cache != NULL)
+ return cache;
+
+ CRYPTO_STATIC_MUTEX_lock_write(&g_x509_policy_cache_lock);
if (x->policy_cache == NULL)
- {
- CRYPTO_w_lock(CRYPTO_LOCK_X509);
- policy_cache_new(x);
- CRYPTO_w_unlock(CRYPTO_LOCK_X509);
- }
+ policy_cache_new(x);
+ cache = x->policy_cache;
+ CRYPTO_STATIC_MUTEX_unlock(&g_x509_policy_cache_lock);
- return x->policy_cache;
-
+ return cache;
}
X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c
index 3f175c9..8ae8a06 100644
--- a/crypto/x509v3/v3_purp.c
+++ b/crypto/x509v3/v3_purp.c
@@ -67,6 +67,8 @@
#include <openssl/x509_vfy.h>
#include <openssl/x509v3.h>
+#include "../internal.h"
+
static void x509v3_cache_extensions(X509 *x);
@@ -114,9 +116,7 @@
int idx;
const X509_PURPOSE *pt;
if(!(x->ex_flags & EXFLAG_SET)) {
- CRYPTO_w_lock(CRYPTO_LOCK_X509);
x509v3_cache_extensions(x);
- CRYPTO_w_unlock(CRYPTO_LOCK_X509);
}
if(id == -1) return 1;
idx = X509_PURPOSE_get_by_id(id);
@@ -367,6 +367,15 @@
setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
}
+/* g_x509_cache_extensions_lock is used to protect against concurrent calls to
+ * |x509v3_cache_extensions|. Ideally this would be done with a |CRYPTO_once_t|
+ * in the |X509| structure, but |CRYPTO_once_t| isn't public.
+ *
+ * Note: it's not entirely clear whether this lock is needed. Not all paths to
+ * this function took a lock in OpenSSL. */
+static struct CRYPTO_STATIC_MUTEX g_x509_cache_extensions_lock =
+ CRYPTO_STATIC_MUTEX_INIT;
+
static void x509v3_cache_extensions(X509 *x)
{
BASIC_CONSTRAINTS *bs;
@@ -377,7 +386,15 @@
X509_EXTENSION *ex;
size_t i;
int j;
- if(x->ex_flags & EXFLAG_SET) return;
+
+ CRYPTO_STATIC_MUTEX_lock_write(&g_x509_cache_extensions_lock);
+
+ if(x->ex_flags & EXFLAG_SET)
+ {
+ CRYPTO_STATIC_MUTEX_unlock(&g_x509_cache_extensions_lock);
+ return;
+ }
+
X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
/* V1 should mean no extensions ... */
if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1;
@@ -501,6 +518,8 @@
}
}
x->ex_flags |= EXFLAG_SET;
+
+ CRYPTO_STATIC_MUTEX_unlock(&g_x509_cache_extensions_lock);
}
/* CA checks common to all purposes
@@ -544,9 +563,7 @@
int X509_check_ca(X509 *x)
{
if(!(x->ex_flags & EXFLAG_SET)) {
- CRYPTO_w_lock(CRYPTO_LOCK_X509);
x509v3_cache_extensions(x);
- CRYPTO_w_unlock(CRYPTO_LOCK_X509);
}
return check_ca(x);