diff options
Diffstat (limited to 'src/crypto/x509v3')
-rw-r--r-- | src/crypto/x509v3/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/crypto/x509v3/pcy_cache.c | 27 | ||||
-rw-r--r-- | src/crypto/x509v3/v3_purp.c | 27 | ||||
-rw-r--r-- | src/crypto/x509v3/v3_utl.c | 5 |
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. |