X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=crypto%2Fx509%2Fby_dir.c;h=3fc52be474ff958c80c6646468e355280cd9f10b;hb=3147785eb23bb27080a0b7accbbff46ac471e86c;hp=b67b6c5648b589c7c9991cf0e37f8b4b16af26d1;hpb=b425001010044adbdbcd98f8682694b30b73bbf4;p=openssl.git diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c index b67b6c5648..3fc52be474 100644 --- a/crypto/x509/by_dir.c +++ b/crypto/x509/by_dir.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,7 +7,16 @@ * https://www.openssl.org/source/license.html */ -#include "e_os.h" +#if defined (__TANDEM) && defined (_SPT_MODEL_) + /* + * These definitions have to come first in SPT due to scoping of the + * declarations in c99 associated with SPT use of stat. + */ +# include +# include +#endif + +#include "internal/e_os.h" #include "internal/cryptlib.h" #include #include @@ -79,15 +88,20 @@ static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, switch (cmd) { case X509_L_ADD_DIR: if (argl == X509_FILETYPE_DEFAULT) { - const char *dir = ossl_safe_getenv(X509_get_default_cert_dir_env()); + /* If SSL_CERT_PATH is provided and non-empty, use that. */ + const char *dir = ossl_safe_getenv(X509_get_default_cert_path_env()); + + /* Fallback to SSL_CERT_DIR. */ + if (dir == NULL) + dir = ossl_safe_getenv(X509_get_default_cert_dir_env()); - if (dir) - ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM); - else - ret = add_cert_dir(ld, X509_get_default_cert_dir(), - X509_FILETYPE_PEM); + /* Fallback to built-in default. */ + if (dir == NULL) + dir = X509_get_default_cert_dir(); + + ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM); if (!ret) { - X509err(X509_F_DIR_CTRL, X509_R_LOADING_CERT_DIR); + ERR_raise(ERR_LIB_X509, X509_R_LOADING_CERT_DIR); } } else ret = add_cert_dir(ld, argp, (int)argl); @@ -100,20 +114,18 @@ static int new_dir(X509_LOOKUP *lu) { BY_DIR *a = OPENSSL_malloc(sizeof(*a)); - if (a == NULL) { - X509err(X509_F_NEW_DIR, ERR_R_MALLOC_FAILURE); + if (a == NULL) return 0; - } if ((a->buffer = BUF_MEM_new()) == NULL) { - X509err(X509_F_NEW_DIR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_BN_LIB); goto err; } a->dirs = NULL; a->lock = CRYPTO_THREAD_lock_new(); if (a->lock == NULL) { BUF_MEM_free(a->buffer); - X509err(X509_F_NEW_DIR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto err; } lu->method_data = a; @@ -163,7 +175,7 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) const char *s, *ss, *p; if (dir == NULL || *dir == '\0') { - X509err(X509_F_ADD_CERT_DIR, X509_R_INVALID_DIRECTORY); + ERR_raise(ERR_LIB_X509, X509_R_INVALID_DIRECTORY); return 0; } @@ -188,15 +200,13 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) if (ctx->dirs == NULL) { ctx->dirs = sk_BY_DIR_ENTRY_new_null(); if (!ctx->dirs) { - X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); return 0; } } ent = OPENSSL_malloc(sizeof(*ent)); - if (ent == NULL) { - X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE); + if (ent == NULL) return 0; - } ent->dir_type = type; ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp); ent->dir = OPENSSL_strndup(ss, len); @@ -206,7 +216,7 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) } if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { by_dir_entry_free(ent); - X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); return 0; } } @@ -237,24 +247,24 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, if (type == X509_LU_X509) { data.st_x509.cert_info.subject = (X509_NAME *)name; /* won't modify it */ stmp.data.x509 = &data.st_x509; - postfix = ""; } else if (type == X509_LU_CRL) { data.crl.crl.issuer = (X509_NAME *)name; /* won't modify it */ stmp.data.crl = &data.crl; postfix = "r"; } else { - X509err(0, X509_R_WRONG_LOOKUP_TYPE); + ERR_raise(ERR_LIB_X509, X509_R_WRONG_LOOKUP_TYPE); goto finish; } if ((b = BUF_MEM_new()) == NULL) { - X509err(0, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB); goto finish; } ctx = (BY_DIR *)xl->method_data; - - h = X509_NAME_hash(name); + h = X509_NAME_hash_ex(name, libctx, propq, &i); + if (i == 0) + goto finish; for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { BY_DIR_ENTRY *ent; int idx; @@ -263,12 +273,13 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1; if (!BUF_MEM_grow(b, j)) { - X509err(0, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB); goto finish; } if (type == X509_LU_CRL && ent->hashes) { htmp.hash = h; - CRYPTO_THREAD_read_lock(ctx->lock); + if (!CRYPTO_THREAD_read_lock(ctx->lock)) + goto finish; idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); if (idx >= 0) { hent = sk_BY_DIR_HASH_value(ent->hashes, idx); @@ -343,10 +354,15 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j); X509_STORE_unlock(xl->store_ctx); - /* If a CRL, update the last file suffix added for this */ - - if (type == X509_LU_CRL) { - CRYPTO_THREAD_write_lock(ctx->lock); + /* + * If a CRL, update the last file suffix added for this. + * We don't need to add an entry if k is 0 as this is the initial value. + * This avoids the need for a write lock and sort operation in the + * simple case where no CRL is present for a hash. + */ + if (type == X509_LU_CRL && k > 0) { + if (!CRYPTO_THREAD_write_lock(ctx->lock)) + goto finish; /* * Look for entry again in case another thread added an entry * first. @@ -360,7 +376,6 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, hent = OPENSSL_malloc(sizeof(*hent)); if (hent == NULL) { CRYPTO_THREAD_unlock(ctx->lock); - X509err(0, ERR_R_MALLOC_FAILURE); ok = 0; goto finish; } @@ -369,10 +384,16 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { CRYPTO_THREAD_unlock(ctx->lock); OPENSSL_free(hent); - X509err(0, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); ok = 0; goto finish; } + + /* + * Ensure stack is sorted so that subsequent sk_BY_DIR_HASH_find + * will not mutate the stack and therefore require a write lock. + */ + sk_BY_DIR_HASH_sort(ent->hashes); } else if (hent->suffix < k) { hent->suffix = k; }