Add a null provider which implements no algorithms.

By loading the null provider into the default context, it is possible
to verify that it is not accidentally being used.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11488)
This commit is contained in:
Pauli 2020-04-08 12:02:34 +10:00
parent f5056577ba
commit 7b4344ac3e
5 changed files with 169 additions and 1 deletions

View File

@ -11,6 +11,7 @@
#include "provider_local.h"
OSSL_provider_init_fn ossl_default_provider_init;
OSSL_provider_init_fn ossl_null_provider_init;
OSSL_provider_init_fn fips_intern_provider_init;
#ifdef STATIC_LEGACY
OSSL_provider_init_fn ossl_legacy_provider_init;
@ -23,6 +24,7 @@ const struct predefined_providers_st predefined_providers[] = {
# ifdef STATIC_LEGACY
{ "legacy", ossl_legacy_provider_init, 0 },
# endif
{ "null", ossl_null_provider_init, 0 },
#endif
{ NULL, NULL, 0 }
};

View File

@ -0,0 +1,35 @@
=pod
=head1 NAME
OSSL_PROVIDER-null - OpenSSL null provider
=head1 DESCRIPTION
The OpenSSL null provider supplies no algorithms.
It can used to guarantee that the default library context and a fallback
provider will not be accidentally accessed.
=head2 Properties
The null provider defines no properties.
=head1 OPERATIONS AND ALGORITHMS
The OpenSSL null provider supports no operations and algorithms.
=head1 SEE ALSO
L<provider(7)>
=head1 COPYRIGHT
Copyright 2020 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

@ -151,3 +151,13 @@ IF[{- !$disabled{legacy} -}]
SOURCE[$LEGACYGOAL]=legacyprov.c
INCLUDE[$LEGACYGOAL]=../include implementations/include
ENDIF
#
# Null provider stuff
#
# Because the null provider is built in, it means that libcrypto must
# include all the object files that are needed.
$NULLGOAL=../libcrypto
SOURCE[$NULLGOAL]=nullprov.c

106
providers/nullprov.c Normal file
View File

@ -0,0 +1,106 @@
/*
* Copyright 2020 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 <string.h>
#include <stdio.h>
#include <openssl/core.h>
#include <openssl/core_numbers.h>
#include <openssl/core_names.h>
#include <openssl/params.h>
#include "prov/implementations.h"
OSSL_provider_init_fn ossl_null_provider_init;
/* Functions provided by the core */
static OSSL_core_gettable_params_fn *c_gettable_params = NULL;
static OSSL_core_get_params_fn *c_get_params = NULL;
/* Parameters we provide to the core */
static const OSSL_ITEM null_param_types[] = {
{ OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_NAME },
{ OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_VERSION },
{ OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_BUILDINFO },
{ 0, NULL }
};
static const OSSL_ITEM *null_gettable_params(const OSSL_PROVIDER *prov)
{
return null_param_types;
}
static int null_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
{
OSSL_PARAM *p;
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME);
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "OpenSSL Null Provider"))
return 0;
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_VERSION);
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR))
return 0;
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO);
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_FULL_VERSION_STR))
return 0;
return 1;
}
static const OSSL_ALGORITHM *null_query(OSSL_PROVIDER *prov,
int operation_id,
int *no_cache)
{
*no_cache = 0;
return NULL;
}
/* Functions we provide to the core */
static const OSSL_DISPATCH null_dispatch_table[] = {
{ OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))null_gettable_params },
{ OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))null_get_params },
{ OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))null_query },
{ 0, NULL }
};
int ossl_null_provider_init(const OSSL_PROVIDER *provider,
const OSSL_DISPATCH *in,
const OSSL_DISPATCH **out,
void **provctx)
{
OSSL_core_get_library_context_fn *c_get_libctx = NULL;
for (; in->function_id != 0; in++) {
switch (in->function_id) {
case OSSL_FUNC_CORE_GETTABLE_PARAMS:
c_gettable_params = OSSL_get_core_gettable_params(in);
break;
case OSSL_FUNC_CORE_GET_PARAMS:
c_get_params = OSSL_get_core_get_params(in);
break;
case OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT:
c_get_libctx = OSSL_get_core_get_library_context(in);
break;
/* Just ignore anything we don't understand */
default:
break;
}
}
if (c_get_libctx == NULL)
return 0;
*out = null_dispatch_table;
/*
* We want to make sure that all calls from this provider that requires
* a library context use the same context as the one used to call our
* functions. We do that by passing it along as the provider context.
*/
*provctx = c_get_libctx(provider);
return 1;
}

View File

@ -14,7 +14,7 @@ use OpenSSL::Test;
setup("test_provider");
plan tests => 7;
plan tests => 9;
SKIP: {
skip "No default provider?", 6
@ -45,3 +45,18 @@ plan tests => 7;
}
}
SKIP: {
skip "No null provider?", 1
unless ok(run(app([qw(openssl provider null)])),
"try running 'openssl provider null'");
my @cmd = ('openssl', 'provider', '-vvv', 'null');
my @lines = ( map { (my $x = $_) =~ s|\R$||; $x }
run(app([@cmd]), capture => 1) );
my $curr = scalar @lines;
my $cmp = "$curr == 1";
ok(eval $cmp,
"'openssl provider $_ default' line count == 1");
}