提交 e0624f0d 编写于 作者: S Shane Lontis

Add default property API's to enable and test for fips

Reviewed-by: NTomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/11239)
上级 e908f292
......@@ -2572,6 +2572,7 @@ EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED:179:\
EVP_R_PRIVATE_KEY_DECODE_ERROR:145:private key decode error
EVP_R_PRIVATE_KEY_ENCODE_ERROR:146:private key encode error
EVP_R_PUBLIC_KEY_NOT_RSA:106:public key not rsa
EVP_R_SET_DEFAULT_PROPERTY_FAILURE:208:set default property failure
EVP_R_TOO_MANY_RECORDS:183:too many records
EVP_R_UNKNOWN_CIPHER:160:unknown cipher
EVP_R_UNKNOWN_DIGEST:161:unknown digest
......
......@@ -19,7 +19,6 @@ DEFINE_STACK_OF(CONF_VALUE)
/* Algorithm configuration module. */
/* TODO(3.0): the config module functions should be passed a library context */
static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
{
int i;
......@@ -46,14 +45,17 @@ static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
}
/*
* fips_mode is deprecated and should not be used in new
* configurations. Old configurations are likely to ONLY
* have this, so we assume that no default properties have
* been set before this.
* configurations.
*/
if (m > 0)
EVP_set_default_properties(NULL, "fips=yes");
if (!EVP_default_properties_enable_fips(cnf->libctx, m > 0)) {
EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_SET_DEFAULT_PROPERTY_FAILURE);
return 0;
}
} else if (strcmp(oval->name, "default_properties") == 0) {
EVP_set_default_properties(NULL, oval->value);
if (!EVP_set_default_properties(cnf->libctx, oval->value)) {
EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_SET_DEFAULT_PROPERTY_FAILURE);
return 0;
}
} else {
EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION);
ERR_add_error_data(4, "name=", oval->name,
......
......@@ -133,6 +133,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PRIVATE_KEY_ENCODE_ERROR),
"private key encode error"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_SET_DEFAULT_PROPERTY_FAILURE),
"set default property failure"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_TOO_MANY_RECORDS), "too many records"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_CIPHER), "unknown cipher"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_DIGEST), "unknown digest"},
......
......@@ -367,10 +367,42 @@ int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq)
if (store != NULL)
return ossl_method_store_set_global_properties(store, propq);
EVPerr(EVP_F_EVP_SET_DEFAULT_PROPERTIES, ERR_R_INTERNAL_ERROR);
EVPerr(0, ERR_R_INTERNAL_ERROR);
return 0;
}
static int evp_default_properties_merge(OPENSSL_CTX *libctx, const char *propq)
{
OSSL_METHOD_STORE *store = get_evp_method_store(libctx);
if (store != NULL)
return ossl_method_store_merge_global_properties(store, propq);
EVPerr(0, ERR_R_INTERNAL_ERROR);
return 0;
}
static int evp_default_property_is_enabled(OPENSSL_CTX *libctx,
const char *prop_name)
{
OSSL_METHOD_STORE *store = get_evp_method_store(libctx);
return ossl_method_store_global_property_is_enabled(store, prop_name);
}
int EVP_default_properties_is_fips_enabled(OPENSSL_CTX *libctx)
{
return evp_default_property_is_enabled(libctx, "fips");
}
int EVP_default_properties_enable_fips(OPENSSL_CTX *libctx, int enable)
{
const char *query = (enable != 0) ? "fips=yes" : "-fips";
return evp_default_properties_merge(libctx, query);
}
struct do_all_data_st {
void (*user_fn)(void *method, void *arg);
void *user_arg;
......
......@@ -362,8 +362,24 @@ fin:
return ret;
}
int ossl_method_store_global_property_is_enabled(OSSL_METHOD_STORE *store,
const char *prop_name)
{
int ret = 0;
if (store == NULL)
return 0;
ossl_property_read_lock(store);
ret = ossl_property_is_enabled(store->ctx, prop_name,
store->global_properties);
ossl_property_unlock(store);
return ret;
}
int ossl_method_store_set_global_properties(OSSL_METHOD_STORE *store,
const char *prop_query) {
const char *prop_query)
{
int ret = 0;
if (store == NULL)
......@@ -371,9 +387,11 @@ int ossl_method_store_set_global_properties(OSSL_METHOD_STORE *store,
ossl_property_write_lock(store);
ossl_method_cache_flush_all(store);
ossl_property_free(store->global_properties);
store->global_properties = NULL;
if (prop_query == NULL) {
ossl_property_free(store->global_properties);
store->global_properties = NULL;
ossl_property_unlock(store);
return 1;
}
......@@ -383,6 +401,45 @@ int ossl_method_store_set_global_properties(OSSL_METHOD_STORE *store,
return ret;
}
int ossl_method_store_merge_global_properties(OSSL_METHOD_STORE *store,
const char *prop_query)
{
int ret = 0;
OSSL_PROPERTY_LIST *prop = NULL, *global;
if (store == NULL)
return 1;
ossl_property_write_lock(store);
ossl_method_cache_flush_all(store);
if (prop_query == NULL) {
ossl_property_free(store->global_properties);
store->global_properties = NULL;
goto success;
}
prop = ossl_parse_query(store->ctx, prop_query);
if (prop == NULL)
goto end;
if (store->global_properties == NULL) {
store->global_properties = prop;
prop = NULL;
goto success;
}
global = ossl_property_merge(prop, store->global_properties);
if (global == NULL)
goto end;
ossl_property_free(store->global_properties);
store->global_properties = global;
success:
ret = 1;
end:
ossl_property_unlock(store);
ossl_property_free(prop);
return ret;
}
static void impl_cache_flush_alg(ossl_uintmax_t idx, ALGORITHM *alg)
{
lh_QUERY_doall(alg->cache, &impl_cache_free);
......
......@@ -453,6 +453,35 @@ int ossl_property_has_optional(const OSSL_PROPERTY_LIST *query)
return query->has_optional ? 1 : 0;
}
int ossl_property_is_enabled(OPENSSL_CTX *ctx, const char *property_name,
const OSSL_PROPERTY_LIST *prop_list)
{
int i;
OSSL_PROPERTY_IDX name_id;
const PROPERTY_DEFINITION *prop = NULL;
if (prop_list == NULL)
return 0;
if (!parse_name(ctx, &property_name, 0, &name_id))
return 0;
prop = prop_list->properties;
for (i = 0; i < prop_list->n; ++i) {
if (prop[i].name_idx == name_id) {
/* Do a separate check for override as it does not set type */
if (prop[i].optional || prop[i].oper == PROPERTY_OVERRIDE)
return 0;
return (prop[i].type == PROPERTY_TYPE_STRING
&& ((prop[i].oper == PROPERTY_OPER_EQ
&& prop[i].v.str_val == ossl_property_true)
|| (prop[i].oper == PROPERTY_OPER_NE
&& prop[i].v.str_val != ossl_property_true)));
}
}
return 0;
}
/*
* Compare a query against a definition.
* Return the number of clauses matched or -1 if a mandatory clause is false.
......
......@@ -2,7 +2,8 @@
=head1 NAME
EVP_set_default_properties
EVP_set_default_properties, EVP_default_properties_enable_fips,
EVP_default_properties_is_fips_enabled
- Set default properties for future algorithm fetches
=head1 SYNOPSIS
......@@ -10,6 +11,8 @@ EVP_set_default_properties
#include <openssl/evp.h>
int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq);
int EVP_default_properties_enable_fips(OPENSSL_CTX *libctx, int enable);
int EVP_default_properties_is_fips_enabled(OPENSSL_CTX *libctx);
=head1 DESCRIPTION
......@@ -27,10 +30,22 @@ given with I<libctx> (NULL signifies the default library context).
Any previous default property for the specified library context will
be dropped.
EVP_default_properties_enable_fips() sets the 'fips=yes' to be a default property
if I<enable> is non zero, otherwise it clears 'fips' from the default property
query for the given I<libctx>. It merges the fips default property query with any
existing query strings that have been set via EVP_set_default_properties().
EVP_default_properties_is_fips_enabled() indicates if 'fips=yes' is a default
property for the given I<libctx>.
=head1 RETURN VALUES
EVP_set_default_properties() returns 1 on success, or 0 on failure.
The latter adds an error on the error stack.
EVP_set_default_properties() and EVP_default_properties_enable_fips() return 1
on success, or 0 on failure. An error is placed on the the error stack if a
failure occurs.
EVP_default_properties_is_fips_enabled() returns 1 if the 'fips=true' default
property is set for the given I<libctx>, otherwise it returns 0.
=head1 SEE ALSO
......@@ -42,7 +57,7 @@ The functions described here were added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
Copyright 2019-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
......
......@@ -26,6 +26,8 @@ OSSL_PROPERTY_LIST *ossl_parse_query(OPENSSL_CTX *ctx, const char *s);
/* Property checker of query vs definition */
int ossl_property_match_count(const OSSL_PROPERTY_LIST *query,
const OSSL_PROPERTY_LIST *defn);
int ossl_property_is_enabled(OPENSSL_CTX *ctx, const char *property_name,
const OSSL_PROPERTY_LIST *prop_list);
/* Free a parsed property list */
void ossl_property_free(OSSL_PROPERTY_LIST *p);
......@@ -43,6 +45,10 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid,
const char *prop_query, void **result);
int ossl_method_store_set_global_properties(OSSL_METHOD_STORE *store,
const char *prop_query);
int ossl_method_store_merge_global_properties(OSSL_METHOD_STORE *store,
const char *prop_query);
int ossl_method_store_global_property_is_enabled(OSSL_METHOD_STORE *store,
const char *prop_name);
/* property query cache functions */
int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, int nid,
......
......@@ -78,6 +78,8 @@ extern "C" {
#endif
int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq);
int EVP_default_properties_is_fips_enabled(OPENSSL_CTX *libctx);
int EVP_default_properties_enable_fips(OPENSSL_CTX *libctx, int enable);
# define EVP_PKEY_MO_SIGN 0x0001
# define EVP_PKEY_MO_VERIFY 0x0002
......
......@@ -235,6 +235,7 @@ int ERR_load_EVP_strings(void);
# define EVP_R_PRIVATE_KEY_DECODE_ERROR 145
# define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146
# define EVP_R_PUBLIC_KEY_NOT_RSA 106
# define EVP_R_SET_DEFAULT_PROPERTY_FAILURE 208
# define EVP_R_TOO_MANY_RECORDS 183
# define EVP_R_UNKNOWN_CIPHER 160
# define EVP_R_UNKNOWN_DIGEST 161
......
......@@ -9,6 +9,7 @@
*/
#include <stdarg.h>
#include <openssl/evp.h>
#include "testutil.h"
#include "internal/nelem.h"
#include "internal/property.h"
......@@ -383,6 +384,35 @@ err:
return res;
}
static int test_fips_mode(void)
{
int ret = 0;
OPENSSL_CTX *ctx = NULL;
if (!TEST_ptr(ctx = OPENSSL_CTX_new()))
goto err;
ret = TEST_true(EVP_set_default_properties(ctx, "default=yes,fips=yes"))
&& TEST_true(EVP_default_properties_is_fips_enabled(ctx))
&& TEST_true(EVP_set_default_properties(ctx, "fips=no,default=yes"))
&& TEST_false(EVP_default_properties_is_fips_enabled(ctx))
&& TEST_true(EVP_set_default_properties(ctx, "fips=no"))
&& TEST_false(EVP_default_properties_is_fips_enabled(ctx))
&& TEST_true(EVP_set_default_properties(ctx, "fips!=no"))
&& TEST_true(EVP_default_properties_is_fips_enabled(ctx))
&& TEST_true(EVP_set_default_properties(ctx, "fips=no"))
&& TEST_false(EVP_default_properties_is_fips_enabled(ctx))
&& TEST_true(EVP_set_default_properties(ctx, "fips=no,default=yes"))
&& TEST_true(EVP_default_properties_enable_fips(ctx, 1))
&& TEST_true(EVP_default_properties_is_fips_enabled(ctx))
&& TEST_true(EVP_default_properties_enable_fips(ctx, 0))
&& TEST_false(EVP_default_properties_is_fips_enabled(ctx));
err:
OPENSSL_CTX_free(ctx);
return ret;
}
int setup_tests(void)
{
ADD_TEST(test_property_string);
......@@ -393,5 +423,6 @@ int setup_tests(void)
ADD_TEST(test_register_deregister);
ADD_TEST(test_property);
ADD_TEST(test_query_cache_stochastic);
ADD_TEST(test_fips_mode);
return 1;
}
......@@ -5079,3 +5079,5 @@ X509_REQ_set0_signature ? 3_0_0 EXIST::FUNCTION:
X509_REQ_set1_signature_algo ? 3_0_0 EXIST::FUNCTION:
OSSL_PARAM_modified ? 3_0_0 EXIST::FUNCTION:
OSSL_PARAM_set_all_unmodified ? 3_0_0 EXIST::FUNCTION:
EVP_default_properties_is_fips_enabled ? 3_0_0 EXIST::FUNCTION:
EVP_default_properties_enable_fips ? 3_0_0 EXIST::FUNCTION:
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册