Latest update.
This commit is contained in:
+78
-42
@@ -21,21 +21,30 @@
|
||||
#include "crypto/sparse_array.h"
|
||||
#include "property_local.h"
|
||||
|
||||
/* The number of elements in the query cache before we initiate a flush */
|
||||
/*
|
||||
* The number of elements in the query cache before we initiate a flush.
|
||||
* If reducing this, also ensure the stochastic test in test/property_test.c
|
||||
* isn't likely to fail.
|
||||
*/
|
||||
#define IMPL_CACHE_FLUSH_THRESHOLD 500
|
||||
|
||||
typedef struct {
|
||||
void *method;
|
||||
int (*up_ref)(void *);
|
||||
void (*free)(void *);
|
||||
} METHOD;
|
||||
|
||||
typedef struct {
|
||||
const OSSL_PROVIDER *provider;
|
||||
OSSL_PROPERTY_LIST *properties;
|
||||
void *method;
|
||||
void (*method_destruct)(void *);
|
||||
METHOD method;
|
||||
} IMPLEMENTATION;
|
||||
|
||||
DEFINE_STACK_OF(IMPLEMENTATION)
|
||||
|
||||
typedef struct {
|
||||
const char *query;
|
||||
void *method;
|
||||
METHOD method;
|
||||
char body[1];
|
||||
} QUERY;
|
||||
|
||||
@@ -67,6 +76,16 @@ DEFINE_SPARSE_ARRAY_OF(ALGORITHM);
|
||||
static void ossl_method_cache_flush(OSSL_METHOD_STORE *store, int nid);
|
||||
static void ossl_method_cache_flush_all(OSSL_METHOD_STORE *c);
|
||||
|
||||
static int ossl_method_up_ref(METHOD *method)
|
||||
{
|
||||
return (*method->up_ref)(method->method);
|
||||
}
|
||||
|
||||
static void ossl_method_free(METHOD *method)
|
||||
{
|
||||
(*method->free)(method->method);
|
||||
}
|
||||
|
||||
int ossl_property_read_lock(OSSL_METHOD_STORE *p)
|
||||
{
|
||||
return p != NULL ? CRYPTO_THREAD_read_lock(p->lock) : 0;
|
||||
@@ -95,15 +114,17 @@ static int query_cmp(const QUERY *a, const QUERY *b)
|
||||
static void impl_free(IMPLEMENTATION *impl)
|
||||
{
|
||||
if (impl != NULL) {
|
||||
if (impl->method_destruct)
|
||||
impl->method_destruct(impl->method);
|
||||
ossl_method_free(&impl->method);
|
||||
OPENSSL_free(impl);
|
||||
}
|
||||
}
|
||||
|
||||
static void impl_cache_free(QUERY *elem)
|
||||
{
|
||||
OPENSSL_free(elem);
|
||||
if (elem != NULL) {
|
||||
ossl_method_free(&elem->method);
|
||||
OPENSSL_free(elem);
|
||||
}
|
||||
}
|
||||
|
||||
static void alg_cleanup(ossl_uintmax_t idx, ALGORITHM *a)
|
||||
@@ -132,7 +153,7 @@ OSSL_METHOD_STORE *ossl_method_store_new(OPENSSL_CTX *ctx)
|
||||
return NULL;
|
||||
}
|
||||
if ((res->lock = CRYPTO_THREAD_lock_new()) == NULL) {
|
||||
OPENSSL_free(res->algs);
|
||||
ossl_sa_ALGORITHM_free(res->algs);
|
||||
OPENSSL_free(res);
|
||||
return NULL;
|
||||
}
|
||||
@@ -180,13 +201,14 @@ int ossl_method_store_add(OSSL_METHOD_STORE *store, const OSSL_PROVIDER *prov,
|
||||
impl = OPENSSL_malloc(sizeof(*impl));
|
||||
if (impl == NULL)
|
||||
return 0;
|
||||
if (method_up_ref != NULL && !method_up_ref(method)) {
|
||||
impl->method.method = method;
|
||||
impl->method.up_ref = method_up_ref;
|
||||
impl->method.free = method_destruct;
|
||||
if (!ossl_method_up_ref(&impl->method)) {
|
||||
OPENSSL_free(impl);
|
||||
return 0;
|
||||
}
|
||||
impl->provider = prov;
|
||||
impl->method = method;
|
||||
impl->method_destruct = method_destruct;
|
||||
|
||||
/*
|
||||
* Insert into the hash table if required.
|
||||
@@ -262,10 +284,10 @@ int ossl_method_store_remove(OSSL_METHOD_STORE *store, int nid,
|
||||
for (i = 0; i < sk_IMPLEMENTATION_num(alg->impls); i++) {
|
||||
IMPLEMENTATION *impl = sk_IMPLEMENTATION_value(alg->impls, i);
|
||||
|
||||
if (impl->method == method) {
|
||||
if (impl->method.method == method) {
|
||||
impl_free(impl);
|
||||
sk_IMPLEMENTATION_delete(alg->impls, i);
|
||||
ossl_property_unlock(store);
|
||||
impl_free(impl);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -279,6 +301,7 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid,
|
||||
ALGORITHM *alg;
|
||||
IMPLEMENTATION *impl;
|
||||
OSSL_PROPERTY_LIST *pq = NULL, *p2;
|
||||
METHOD *best_method = NULL;
|
||||
int ret = 0;
|
||||
int j, best = -1, score, optional;
|
||||
|
||||
@@ -302,7 +325,7 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid,
|
||||
|
||||
if (prop_query == NULL) {
|
||||
if ((impl = sk_IMPLEMENTATION_value(alg->impls, 0)) != NULL) {
|
||||
*method = impl->method;
|
||||
best_method = &impl->method;
|
||||
ret = 1;
|
||||
}
|
||||
goto fin;
|
||||
@@ -322,14 +345,18 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid,
|
||||
impl = sk_IMPLEMENTATION_value(alg->impls, j);
|
||||
score = ossl_property_match_count(pq, impl->properties);
|
||||
if (score > best) {
|
||||
*method = impl->method;
|
||||
best_method = &impl->method;
|
||||
best = score;
|
||||
ret = 1;
|
||||
if (!optional)
|
||||
goto fin;
|
||||
best = score;
|
||||
}
|
||||
}
|
||||
fin:
|
||||
if (ret && ossl_method_up_ref(best_method))
|
||||
*method = best_method->method;
|
||||
else
|
||||
ret = 0;
|
||||
ossl_property_unlock(store);
|
||||
ossl_property_free(pq);
|
||||
return ret;
|
||||
@@ -414,7 +441,7 @@ static void impl_cache_flush_cache(QUERY *c, IMPL_CACHE_FLUSH *state)
|
||||
state->seed = n;
|
||||
|
||||
if ((n & 1) != 0)
|
||||
OPENSSL_free(lh_QUERY_delete(state->cache, c));
|
||||
impl_cache_free(lh_QUERY_delete(state->cache, c));
|
||||
else
|
||||
state->nelem++;
|
||||
}
|
||||
@@ -446,34 +473,38 @@ int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, int nid,
|
||||
{
|
||||
ALGORITHM *alg;
|
||||
QUERY elem, *r;
|
||||
int res = 0;
|
||||
|
||||
if (nid <= 0 || store == NULL)
|
||||
return 0;
|
||||
|
||||
ossl_property_read_lock(store);
|
||||
alg = ossl_method_store_retrieve(store, nid);
|
||||
if (alg == NULL) {
|
||||
ossl_property_unlock(store);
|
||||
return 0;
|
||||
}
|
||||
if (alg == NULL)
|
||||
goto err;
|
||||
|
||||
elem.query = prop_query != NULL ? prop_query : "";
|
||||
r = lh_QUERY_retrieve(alg->cache, &elem);
|
||||
if (r == NULL) {
|
||||
ossl_property_unlock(store);
|
||||
return 0;
|
||||
if (r == NULL)
|
||||
goto err;
|
||||
if (ossl_method_up_ref(&r->method)) {
|
||||
*method = r->method.method;
|
||||
res = 1;
|
||||
}
|
||||
*method = r->method;
|
||||
err:
|
||||
ossl_property_unlock(store);
|
||||
return 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, int nid,
|
||||
const char *prop_query, void *method)
|
||||
const char *prop_query, void *method,
|
||||
int (*method_up_ref)(void *),
|
||||
void (*method_destruct)(void *))
|
||||
{
|
||||
QUERY elem, *old, *p = NULL;
|
||||
ALGORITHM *alg;
|
||||
size_t len;
|
||||
int res = 1;
|
||||
|
||||
if (nid <= 0 || store == NULL)
|
||||
return 0;
|
||||
@@ -484,36 +515,41 @@ int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, int nid,
|
||||
if (store->need_flush)
|
||||
ossl_method_cache_flush_some(store);
|
||||
alg = ossl_method_store_retrieve(store, nid);
|
||||
if (alg == NULL) {
|
||||
ossl_property_unlock(store);
|
||||
return 0;
|
||||
}
|
||||
if (alg == NULL)
|
||||
goto err;
|
||||
|
||||
if (method == NULL) {
|
||||
elem.query = prop_query;
|
||||
if (lh_QUERY_delete(alg->cache, &elem) != NULL)
|
||||
if ((old = lh_QUERY_delete(alg->cache, &elem)) != NULL) {
|
||||
impl_cache_free(old);
|
||||
store->nelem--;
|
||||
ossl_property_unlock(store);
|
||||
return 1;
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
p = OPENSSL_malloc(sizeof(*p) + (len = strlen(prop_query)));
|
||||
if (p != NULL) {
|
||||
p->query = p->body;
|
||||
p->method = method;
|
||||
p->method.method = method;
|
||||
p->method.up_ref = method_up_ref;
|
||||
p->method.free = method_destruct;
|
||||
if (!ossl_method_up_ref(&p->method))
|
||||
goto err;
|
||||
memcpy((char *)p->query, prop_query, len + 1);
|
||||
if ((old = lh_QUERY_insert(alg->cache, p)) != NULL) {
|
||||
OPENSSL_free(old);
|
||||
ossl_property_unlock(store);
|
||||
return 1;
|
||||
impl_cache_free(old);
|
||||
goto end;
|
||||
}
|
||||
if (!lh_QUERY_error(alg->cache)) {
|
||||
if (++store->nelem >= IMPL_CACHE_FLUSH_THRESHOLD)
|
||||
store->need_flush = 1;
|
||||
ossl_property_unlock(store);
|
||||
return 1;
|
||||
goto end;
|
||||
}
|
||||
ossl_method_free(&p->method);
|
||||
}
|
||||
ossl_property_unlock(store);
|
||||
err:
|
||||
res = 0;
|
||||
OPENSSL_free(p);
|
||||
return 0;
|
||||
end:
|
||||
ossl_property_unlock(store);
|
||||
return res;
|
||||
}
|
||||
@@ -24,8 +24,8 @@ static const ERR_STRING_DATA PROP_str_reasons[] = {
|
||||
"not an octal digit"},
|
||||
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_A_DECIMAL_DIGIT),
|
||||
"not a decimal digit"},
|
||||
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NO_MATCHING_STRING_DELIMETER),
|
||||
"no matching string delimeter"},
|
||||
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NO_MATCHING_STRING_DELIMITER),
|
||||
"no matching string delimiter"},
|
||||
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NO_VALUE), "no value"},
|
||||
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_PARSE_FAILED), "parse failed"},
|
||||
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_STRING_TOO_LONG), "string too long"},
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <openssl/crypto.h>
|
||||
#include "internal/property.h"
|
||||
|
||||
typedef struct ossl_property_list_st OSSL_PROPERTY_LIST;
|
||||
typedef int OSSL_PROPERTY_IDX;
|
||||
|
||||
/* Property string functions */
|
||||
@@ -23,17 +22,9 @@ OSSL_PROPERTY_IDX ossl_property_value(OPENSSL_CTX *ctx, const char *s,
|
||||
/* Property list functions */
|
||||
void ossl_property_free(OSSL_PROPERTY_LIST *p);
|
||||
int ossl_property_has_optional(const OSSL_PROPERTY_LIST *query);
|
||||
int ossl_property_match_count(const OSSL_PROPERTY_LIST *query,
|
||||
const OSSL_PROPERTY_LIST *defn);
|
||||
OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a,
|
||||
const OSSL_PROPERTY_LIST *b);
|
||||
|
||||
/* Property definition functions */
|
||||
OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *s);
|
||||
|
||||
/* Property query functions */
|
||||
OSSL_PROPERTY_LIST *ossl_parse_query(OPENSSL_CTX *ctx, const char *s);
|
||||
|
||||
/* Property definition cache functions */
|
||||
OSSL_PROPERTY_LIST *ossl_prop_defn_get(OPENSSL_CTX *ctx, const char *prop);
|
||||
int ossl_prop_defn_set(OPENSSL_CTX *ctx, const char *prop,
|
||||
|
||||
@@ -203,7 +203,7 @@ static int parse_string(OPENSSL_CTX *ctx, const char *t[], char delim,
|
||||
s++;
|
||||
}
|
||||
if (*s == '\0') {
|
||||
ERR_raise_data(ERR_LIB_PROP, PROP_R_NO_MATCHING_STRING_DELIMETER,
|
||||
ERR_raise_data(ERR_LIB_PROP, PROP_R_NO_MATCHING_STRING_DELIMITER,
|
||||
"HERE-->%c%s", delim, *t);
|
||||
return 0;
|
||||
}
|
||||
@@ -492,7 +492,7 @@ int ossl_property_match_count(const OSSL_PROPERTY_LIST *query,
|
||||
|
||||
/*
|
||||
* Handle the cases of a missing value and a query with no corresponding
|
||||
* definition. The former fails for any comparision except inequality,
|
||||
* definition. The former fails for any comparison except inequality,
|
||||
* the latter is treated as a comparison against the Boolean false.
|
||||
*/
|
||||
if (q[i].type == PROPERTY_TYPE_VALUE_UNDEFINED) {
|
||||
@@ -568,6 +568,8 @@ int ossl_property_parse_init(OPENSSL_CTX *ctx)
|
||||
"version", /* Version number of this provider */
|
||||
"fips", /* FIPS supporting provider */
|
||||
"engine", /* An old style engine masquerading as a provider */
|
||||
"format", /* output format for serializers */
|
||||
"type", /* output type for serializers */
|
||||
};
|
||||
size_t i;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user