summaryrefslogtreecommitdiffstats
path: root/src/crypto/x509v3
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/x509v3')
-rw-r--r--src/crypto/x509v3/CMakeLists.txt4
-rw-r--r--src/crypto/x509v3/pcy_cache.c27
-rw-r--r--src/crypto/x509v3/v3_purp.c27
-rw-r--r--src/crypto/x509v3/v3_utl.c5
4 files changed, 50 insertions, 13 deletions
diff --git a/src/crypto/x509v3/CMakeLists.txt b/src/crypto/x509v3/CMakeLists.txt
index ffa5a4a..c7e6054 100644
--- a/src/crypto/x509v3/CMakeLists.txt
+++ b/src/crypto/x509v3/CMakeLists.txt
@@ -47,6 +47,8 @@ add_executable(
v3name_test
v3nametest.c
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(v3name_test crypto)
@@ -55,6 +57,8 @@ add_executable(
tab_test
tabtest.c
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(tab_test crypto)
diff --git a/src/crypto/x509v3/pcy_cache.c b/src/crypto/x509v3/pcy_cache.c
index 5d59c00..08f20aa 100644
--- a/src/crypto/x509v3/pcy_cache.c
+++ b/src/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 @@ void policy_cache_free(X509_POLICY_CACHE *cache)
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;
- if (x->policy_cache == NULL)
- {
- CRYPTO_w_lock(CRYPTO_LOCK_X509);
- policy_cache_new(x);
- CRYPTO_w_unlock(CRYPTO_LOCK_X509);
- }
+ 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;
- return x->policy_cache;
+ CRYPTO_STATIC_MUTEX_lock_write(&g_x509_policy_cache_lock);
+ if (x->policy_cache == NULL)
+ policy_cache_new(x);
+ cache = x->policy_cache;
+ CRYPTO_STATIC_MUTEX_unlock(&g_x509_policy_cache_lock);
+ return cache;
}
X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
diff --git a/src/crypto/x509v3/v3_purp.c b/src/crypto/x509v3/v3_purp.c
index 3f175c9..8ae8a06 100644
--- a/src/crypto/x509v3/v3_purp.c
+++ b/src/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 X509_check_purpose(X509 *x, int id, int ca)
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 @@ static void setup_crldp(X509 *x)
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 @@ static void x509v3_cache_extensions(X509 *x)
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 @@ static void x509v3_cache_extensions(X509 *x)
}
}
x->ex_flags |= EXFLAG_SET;
+
+ CRYPTO_STATIC_MUTEX_unlock(&g_x509_cache_extensions_lock);
}
/* CA checks common to all purposes
@@ -544,9 +563,7 @@ static int check_ca(const X509 *x)
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);
diff --git a/src/crypto/x509v3/v3_utl.c b/src/crypto/x509v3/v3_utl.c
index 27a91ff..14a2f3b 100644
--- a/src/crypto/x509v3/v3_utl.c
+++ b/src/crypto/x509v3/v3_utl.c
@@ -263,7 +263,10 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
/* We are going to modify the line so copy it first */
linebuf = BUF_strdup(line);
if (linebuf == NULL)
+ {
+ OPENSSL_PUT_ERROR(X509V3, X509V3_parse_list, ERR_R_MALLOC_FAILURE);
goto err;
+ }
state = HDR_NAME;
ntmp = NULL;
/* Go through all characters */
@@ -751,7 +754,7 @@ static const unsigned char *valid_star(const unsigned char *p, size_t len,
if (p[i] == '*')
{
int atstart = (state & LABEL_START);
- int atend = (i == len - 1 || p[i+i] == '.');
+ int atend = (i == len - 1 || p[i+1] == '.');
/*
* At most one wildcard per pattern.
* No wildcards in IDNA labels.