Add internal function ossl_algorithm_do_all()

This function is used to traverse all the implementations provided by
one provider, or all implementation for a specific operation across
all loaded providers, or both, and execute a given function for each
occurence.

This will be used by ossl_method_construct(), but also by information
processing functions.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9356)
This commit is contained in:
Richard Levitte 2019-07-10 23:11:27 +02:00
parent b37066fdf7
commit a883c02faa
5 changed files with 150 additions and 1 deletions

View file

@ -59,7 +59,8 @@ IF[{- !$disabled{asm} && $config{processor} ne '386' -}]
ENDIF
# The Core
$CORE_COMMON=provider_core.c provider_predefined.c core_fetch.c core_namemap.c
$CORE_COMMON=provider_core.c provider_predefined.c \
core_fetch.c core_algorithm.c core_namemap.c
SOURCE[../libcrypto]=$CORE_COMMON provider_conf.c
SOURCE[../providers/fips]=$CORE_COMMON

75
crypto/core_algorithm.c Normal file
View file

@ -0,0 +1,75 @@
/*
* Copyright 2019 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
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <openssl/core.h>
#include <openssl/core_numbers.h>
#include "internal/core.h"
#include "internal/property.h"
#include "internal/provider.h"
struct algorithm_data_st {
OPENSSL_CTX *libctx;
int operation_id; /* May be zero for finding them all */
void (*fn)(OSSL_PROVIDER *, const OSSL_ALGORITHM *, int no_store,
void *data);
void *data;
};
static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata)
{
struct algorithm_data_st *data = cbdata;
int no_store = 0; /* Assume caching is ok */
int first_operation = 1;
int last_operation = OSSL_OP__HIGHEST;
int cur_operation;
int ok = 0;
if (data->operation_id != 0)
first_operation = last_operation = data->operation_id;
for (cur_operation = first_operation;
cur_operation <= last_operation;
cur_operation++) {
const OSSL_ALGORITHM *map =
ossl_provider_query_operation(provider, data->operation_id,
&no_store);
if (map == NULL)
break;
ok = 1; /* As long as we've found *something* */
while (map->algorithm_name != NULL) {
const OSSL_ALGORITHM *thismap = map++;
data->fn(provider, thismap, no_store, data->data);
}
}
return ok;
}
void ossl_algorithm_do_all(OPENSSL_CTX *libctx, int operation_id,
OSSL_PROVIDER *provider,
void (*fn)(OSSL_PROVIDER *provider,
const OSSL_ALGORITHM *algo,
int no_store, void *data),
void *data)
{
struct algorithm_data_st cbdata;
cbdata.libctx = libctx;
cbdata.operation_id = operation_id;
cbdata.fn = fn;
cbdata.data = data;
if (provider == NULL)
ossl_provider_forall_loaded(libctx, algorithm_do_this, &cbdata);
else
algorithm_do_this(provider, &cbdata);
}

View file

@ -0,0 +1,63 @@
=pod
=head1 NAME
ossl_algorithm_do_all - generic algorithm implementation iterator
=head1 SYNOPSIS
void ossl_algorithm_do_all(OPENSSL_CTX *libctx, int operation_id,
OSSL_PROVIDER *provider,
void (*fn)(OSSL_PROVIDER *provider,
const OSSL_ALGORITHM *algo,
int no_store, void *data),
void *data)
=head1 DESCRIPTION
ossl_algorithm_do_all() looks up every algorithm it can find, given a
library context I<libctx>, an operation identity I<operation_id> and a
provider I<provider>.
I<libctx> may be NULL to signify that the default library context should
be used.
I<operation_id> may be zero to signify that all kinds of operations
will be looked up.
I<provider> may be NULL to signify that all loaded providers will be
queried.
For each implementation found, the function I<fn> is called with the
I<provider> for the implementation, the algorithm descriptor I<algo>,
the flag I<no_store> indicating whether the algorithm descriptor may
be remembered or not, and the caller I<data> that was passed to
ossl_algorithm_do_all().
=head1 RETURN VALUES
ossl_algorithm_do_all() doesn't return any value.
=head1 NOTES
The function described here are mainly useful for discovery, and
possibly display of what has been discovered, for example an
application that wants to display the loaded providers and what they
may offer, but also for constructors, such as
L<ossl_construct_method(3)>.
=head1 SEE ALSO
L<ossl_construct_method(3)>, L<EVP_MAC_do_all(3)>
=head1 HISTORY
This functionality was added to OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 2019 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 in the file
LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View file

@ -51,4 +51,11 @@ void *ossl_method_construct(OPENSSL_CTX *ctx, int operation_id,
int force_cache,
OSSL_METHOD_CONSTRUCT_METHOD *mcm, void *mcm_data);
void ossl_algorithm_do_all(OPENSSL_CTX *libctx, int operation_id,
OSSL_PROVIDER *provider,
void (*fn)(OSSL_PROVIDER *provider,
const OSSL_ALGORITHM *algo,
int no_store, void *data),
void *data);
#endif

View file

@ -324,6 +324,9 @@ OSSL_CORE_MAKE_FUNC(void *, OP_keyexch_dupctx, (void *ctx))
OSSL_CORE_MAKE_FUNC(int, OP_keyexch_set_params, (void *ctx,
OSSL_PARAM params[]))
/* Highest known operation number */
# define OSSL_OP__HIGHEST 3
# ifdef __cplusplus
}
# endif