1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <string.h> 11e1051a39Sopenharmony_ci#include <openssl/trace.h> 12e1051a39Sopenharmony_ci#include <openssl/err.h> 13e1051a39Sopenharmony_ci#include <openssl/conf.h> 14e1051a39Sopenharmony_ci#include <openssl/safestack.h> 15e1051a39Sopenharmony_ci#include <openssl/provider.h> 16e1051a39Sopenharmony_ci#include "internal/provider.h" 17e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 18e1051a39Sopenharmony_ci#include "provider_local.h" 19e1051a39Sopenharmony_ci 20e1051a39Sopenharmony_ciDEFINE_STACK_OF(OSSL_PROVIDER) 21e1051a39Sopenharmony_ci 22e1051a39Sopenharmony_ci/* PROVIDER config module */ 23e1051a39Sopenharmony_ci 24e1051a39Sopenharmony_citypedef struct { 25e1051a39Sopenharmony_ci CRYPTO_RWLOCK *lock; 26e1051a39Sopenharmony_ci STACK_OF(OSSL_PROVIDER) *activated_providers; 27e1051a39Sopenharmony_ci} PROVIDER_CONF_GLOBAL; 28e1051a39Sopenharmony_ci 29e1051a39Sopenharmony_cistatic void *prov_conf_ossl_ctx_new(OSSL_LIB_CTX *libctx) 30e1051a39Sopenharmony_ci{ 31e1051a39Sopenharmony_ci PROVIDER_CONF_GLOBAL *pcgbl = OPENSSL_zalloc(sizeof(*pcgbl)); 32e1051a39Sopenharmony_ci 33e1051a39Sopenharmony_ci if (pcgbl == NULL) 34e1051a39Sopenharmony_ci return NULL; 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_ci pcgbl->lock = CRYPTO_THREAD_lock_new(); 37e1051a39Sopenharmony_ci if (pcgbl->lock == NULL) { 38e1051a39Sopenharmony_ci OPENSSL_free(pcgbl); 39e1051a39Sopenharmony_ci return NULL; 40e1051a39Sopenharmony_ci } 41e1051a39Sopenharmony_ci 42e1051a39Sopenharmony_ci return pcgbl; 43e1051a39Sopenharmony_ci} 44e1051a39Sopenharmony_ci 45e1051a39Sopenharmony_cistatic void prov_conf_ossl_ctx_free(void *vpcgbl) 46e1051a39Sopenharmony_ci{ 47e1051a39Sopenharmony_ci PROVIDER_CONF_GLOBAL *pcgbl = vpcgbl; 48e1051a39Sopenharmony_ci 49e1051a39Sopenharmony_ci sk_OSSL_PROVIDER_pop_free(pcgbl->activated_providers, 50e1051a39Sopenharmony_ci ossl_provider_free); 51e1051a39Sopenharmony_ci 52e1051a39Sopenharmony_ci OSSL_TRACE(CONF, "Cleaned up providers\n"); 53e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(pcgbl->lock); 54e1051a39Sopenharmony_ci OPENSSL_free(pcgbl); 55e1051a39Sopenharmony_ci} 56e1051a39Sopenharmony_ci 57e1051a39Sopenharmony_cistatic const OSSL_LIB_CTX_METHOD provider_conf_ossl_ctx_method = { 58e1051a39Sopenharmony_ci /* Must be freed before the provider store is freed */ 59e1051a39Sopenharmony_ci OSSL_LIB_CTX_METHOD_PRIORITY_2, 60e1051a39Sopenharmony_ci prov_conf_ossl_ctx_new, 61e1051a39Sopenharmony_ci prov_conf_ossl_ctx_free, 62e1051a39Sopenharmony_ci}; 63e1051a39Sopenharmony_ci 64e1051a39Sopenharmony_cistatic const char *skip_dot(const char *name) 65e1051a39Sopenharmony_ci{ 66e1051a39Sopenharmony_ci const char *p = strchr(name, '.'); 67e1051a39Sopenharmony_ci 68e1051a39Sopenharmony_ci if (p != NULL) 69e1051a39Sopenharmony_ci return p + 1; 70e1051a39Sopenharmony_ci return name; 71e1051a39Sopenharmony_ci} 72e1051a39Sopenharmony_ci 73e1051a39Sopenharmony_ci/* 74e1051a39Sopenharmony_ci * Parse the provider params section 75e1051a39Sopenharmony_ci * Returns: 76e1051a39Sopenharmony_ci * 1 for success 77e1051a39Sopenharmony_ci * 0 for non-fatal errors 78e1051a39Sopenharmony_ci * < 0 for fatal errors 79e1051a39Sopenharmony_ci */ 80e1051a39Sopenharmony_cistatic int provider_conf_params_internal(OSSL_PROVIDER *prov, 81e1051a39Sopenharmony_ci OSSL_PROVIDER_INFO *provinfo, 82e1051a39Sopenharmony_ci const char *name, const char *value, 83e1051a39Sopenharmony_ci const CONF *cnf, 84e1051a39Sopenharmony_ci STACK_OF(OPENSSL_CSTRING) *visited) 85e1051a39Sopenharmony_ci{ 86e1051a39Sopenharmony_ci STACK_OF(CONF_VALUE) *sect; 87e1051a39Sopenharmony_ci int ok = 1; 88e1051a39Sopenharmony_ci int rc = 0; 89e1051a39Sopenharmony_ci 90e1051a39Sopenharmony_ci sect = NCONF_get_section(cnf, value); 91e1051a39Sopenharmony_ci if (sect != NULL) { 92e1051a39Sopenharmony_ci int i; 93e1051a39Sopenharmony_ci char buffer[512]; 94e1051a39Sopenharmony_ci size_t buffer_len = 0; 95e1051a39Sopenharmony_ci 96e1051a39Sopenharmony_ci OSSL_TRACE1(CONF, "Provider params: start section %s\n", value); 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_ci /* 99e1051a39Sopenharmony_ci * Check to see if the provided section value has already 100e1051a39Sopenharmony_ci * been visited. If it has, then we have a recursive lookup 101e1051a39Sopenharmony_ci * in the configuration which isn't valid. As such we should error 102e1051a39Sopenharmony_ci * out 103e1051a39Sopenharmony_ci */ 104e1051a39Sopenharmony_ci for (i = 0; i < sk_OPENSSL_CSTRING_num(visited); i++) { 105e1051a39Sopenharmony_ci if (sk_OPENSSL_CSTRING_value(visited, i) == value) { 106e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CONF, CONF_R_RECURSIVE_SECTION_REFERENCE); 107e1051a39Sopenharmony_ci return -1; 108e1051a39Sopenharmony_ci } 109e1051a39Sopenharmony_ci } 110e1051a39Sopenharmony_ci 111e1051a39Sopenharmony_ci /* 112e1051a39Sopenharmony_ci * We've not visited this node yet, so record it on the stack 113e1051a39Sopenharmony_ci */ 114e1051a39Sopenharmony_ci if (!sk_OPENSSL_CSTRING_push(visited, value)) 115e1051a39Sopenharmony_ci return -1; 116e1051a39Sopenharmony_ci 117e1051a39Sopenharmony_ci if (name != NULL) { 118e1051a39Sopenharmony_ci OPENSSL_strlcpy(buffer, name, sizeof(buffer)); 119e1051a39Sopenharmony_ci OPENSSL_strlcat(buffer, ".", sizeof(buffer)); 120e1051a39Sopenharmony_ci buffer_len = strlen(buffer); 121e1051a39Sopenharmony_ci } 122e1051a39Sopenharmony_ci 123e1051a39Sopenharmony_ci for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { 124e1051a39Sopenharmony_ci CONF_VALUE *sectconf = sk_CONF_VALUE_value(sect, i); 125e1051a39Sopenharmony_ci 126e1051a39Sopenharmony_ci if (buffer_len + strlen(sectconf->name) >= sizeof(buffer)) { 127e1051a39Sopenharmony_ci sk_OPENSSL_CSTRING_pop(visited); 128e1051a39Sopenharmony_ci return -1; 129e1051a39Sopenharmony_ci } 130e1051a39Sopenharmony_ci buffer[buffer_len] = '\0'; 131e1051a39Sopenharmony_ci OPENSSL_strlcat(buffer, sectconf->name, sizeof(buffer)); 132e1051a39Sopenharmony_ci rc = provider_conf_params_internal(prov, provinfo, buffer, 133e1051a39Sopenharmony_ci sectconf->value, cnf, visited); 134e1051a39Sopenharmony_ci if (rc < 0) { 135e1051a39Sopenharmony_ci sk_OPENSSL_CSTRING_pop(visited); 136e1051a39Sopenharmony_ci return rc; 137e1051a39Sopenharmony_ci } 138e1051a39Sopenharmony_ci } 139e1051a39Sopenharmony_ci sk_OPENSSL_CSTRING_pop(visited); 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_ci OSSL_TRACE1(CONF, "Provider params: finish section %s\n", value); 142e1051a39Sopenharmony_ci } else { 143e1051a39Sopenharmony_ci OSSL_TRACE2(CONF, "Provider params: %s = %s\n", name, value); 144e1051a39Sopenharmony_ci if (prov != NULL) 145e1051a39Sopenharmony_ci ok = ossl_provider_add_parameter(prov, name, value); 146e1051a39Sopenharmony_ci else 147e1051a39Sopenharmony_ci ok = ossl_provider_info_add_parameter(provinfo, name, value); 148e1051a39Sopenharmony_ci } 149e1051a39Sopenharmony_ci 150e1051a39Sopenharmony_ci return ok; 151e1051a39Sopenharmony_ci} 152e1051a39Sopenharmony_ci 153e1051a39Sopenharmony_ci/* 154e1051a39Sopenharmony_ci * recursively parse the provider configuration section 155e1051a39Sopenharmony_ci * of the config file. 156e1051a39Sopenharmony_ci * Returns 157e1051a39Sopenharmony_ci * 1 on success 158e1051a39Sopenharmony_ci * 0 on non-fatal error 159e1051a39Sopenharmony_ci * < 0 on fatal errors 160e1051a39Sopenharmony_ci */ 161e1051a39Sopenharmony_cistatic int provider_conf_params(OSSL_PROVIDER *prov, 162e1051a39Sopenharmony_ci OSSL_PROVIDER_INFO *provinfo, 163e1051a39Sopenharmony_ci const char *name, const char *value, 164e1051a39Sopenharmony_ci const CONF *cnf) 165e1051a39Sopenharmony_ci{ 166e1051a39Sopenharmony_ci int rc; 167e1051a39Sopenharmony_ci STACK_OF(OPENSSL_CSTRING) *visited = sk_OPENSSL_CSTRING_new_null(); 168e1051a39Sopenharmony_ci 169e1051a39Sopenharmony_ci if (visited == NULL) 170e1051a39Sopenharmony_ci return -1; 171e1051a39Sopenharmony_ci 172e1051a39Sopenharmony_ci rc = provider_conf_params_internal(prov, provinfo, name, 173e1051a39Sopenharmony_ci value, cnf, visited); 174e1051a39Sopenharmony_ci 175e1051a39Sopenharmony_ci sk_OPENSSL_CSTRING_free(visited); 176e1051a39Sopenharmony_ci 177e1051a39Sopenharmony_ci return rc; 178e1051a39Sopenharmony_ci} 179e1051a39Sopenharmony_ci 180e1051a39Sopenharmony_cistatic int prov_already_activated(const char *name, 181e1051a39Sopenharmony_ci STACK_OF(OSSL_PROVIDER) *activated) 182e1051a39Sopenharmony_ci{ 183e1051a39Sopenharmony_ci int i, max; 184e1051a39Sopenharmony_ci 185e1051a39Sopenharmony_ci if (activated == NULL) 186e1051a39Sopenharmony_ci return 0; 187e1051a39Sopenharmony_ci 188e1051a39Sopenharmony_ci max = sk_OSSL_PROVIDER_num(activated); 189e1051a39Sopenharmony_ci for (i = 0; i < max; i++) { 190e1051a39Sopenharmony_ci OSSL_PROVIDER *tstprov = sk_OSSL_PROVIDER_value(activated, i); 191e1051a39Sopenharmony_ci 192e1051a39Sopenharmony_ci if (strcmp(OSSL_PROVIDER_get0_name(tstprov), name) == 0) { 193e1051a39Sopenharmony_ci return 1; 194e1051a39Sopenharmony_ci } 195e1051a39Sopenharmony_ci } 196e1051a39Sopenharmony_ci 197e1051a39Sopenharmony_ci return 0; 198e1051a39Sopenharmony_ci} 199e1051a39Sopenharmony_ci 200e1051a39Sopenharmony_cistatic int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name, 201e1051a39Sopenharmony_ci const char *value, const CONF *cnf) 202e1051a39Sopenharmony_ci{ 203e1051a39Sopenharmony_ci int i; 204e1051a39Sopenharmony_ci STACK_OF(CONF_VALUE) *ecmds; 205e1051a39Sopenharmony_ci int soft = 0; 206e1051a39Sopenharmony_ci OSSL_PROVIDER *prov = NULL, *actual = NULL; 207e1051a39Sopenharmony_ci const char *path = NULL; 208e1051a39Sopenharmony_ci long activate = 0; 209e1051a39Sopenharmony_ci int ok = 0; 210e1051a39Sopenharmony_ci int added = 0; 211e1051a39Sopenharmony_ci 212e1051a39Sopenharmony_ci name = skip_dot(name); 213e1051a39Sopenharmony_ci OSSL_TRACE1(CONF, "Configuring provider %s\n", name); 214e1051a39Sopenharmony_ci /* Value is a section containing PROVIDER commands */ 215e1051a39Sopenharmony_ci ecmds = NCONF_get_section(cnf, value); 216e1051a39Sopenharmony_ci 217e1051a39Sopenharmony_ci if (!ecmds) { 218e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_SECTION_ERROR, 219e1051a39Sopenharmony_ci "section=%s not found", value); 220e1051a39Sopenharmony_ci return 0; 221e1051a39Sopenharmony_ci } 222e1051a39Sopenharmony_ci 223e1051a39Sopenharmony_ci /* Find the needed data first */ 224e1051a39Sopenharmony_ci for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) { 225e1051a39Sopenharmony_ci CONF_VALUE *ecmd = sk_CONF_VALUE_value(ecmds, i); 226e1051a39Sopenharmony_ci const char *confname = skip_dot(ecmd->name); 227e1051a39Sopenharmony_ci const char *confvalue = ecmd->value; 228e1051a39Sopenharmony_ci 229e1051a39Sopenharmony_ci OSSL_TRACE2(CONF, "Provider command: %s = %s\n", 230e1051a39Sopenharmony_ci confname, confvalue); 231e1051a39Sopenharmony_ci 232e1051a39Sopenharmony_ci /* First handle some special pseudo confs */ 233e1051a39Sopenharmony_ci 234e1051a39Sopenharmony_ci /* Override provider name to use */ 235e1051a39Sopenharmony_ci if (strcmp(confname, "identity") == 0) 236e1051a39Sopenharmony_ci name = confvalue; 237e1051a39Sopenharmony_ci else if (strcmp(confname, "soft_load") == 0) 238e1051a39Sopenharmony_ci soft = 1; 239e1051a39Sopenharmony_ci /* Load a dynamic PROVIDER */ 240e1051a39Sopenharmony_ci else if (strcmp(confname, "module") == 0) 241e1051a39Sopenharmony_ci path = confvalue; 242e1051a39Sopenharmony_ci else if (strcmp(confname, "activate") == 0) 243e1051a39Sopenharmony_ci activate = 1; 244e1051a39Sopenharmony_ci } 245e1051a39Sopenharmony_ci 246e1051a39Sopenharmony_ci if (activate) { 247e1051a39Sopenharmony_ci PROVIDER_CONF_GLOBAL *pcgbl 248e1051a39Sopenharmony_ci = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_PROVIDER_CONF_INDEX, 249e1051a39Sopenharmony_ci &provider_conf_ossl_ctx_method); 250e1051a39Sopenharmony_ci 251e1051a39Sopenharmony_ci if (pcgbl == NULL || !CRYPTO_THREAD_write_lock(pcgbl->lock)) { 252e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); 253e1051a39Sopenharmony_ci return 0; 254e1051a39Sopenharmony_ci } 255e1051a39Sopenharmony_ci if (!prov_already_activated(name, pcgbl->activated_providers)) { 256e1051a39Sopenharmony_ci /* 257e1051a39Sopenharmony_ci * There is an attempt to activate a provider, so we should disable 258e1051a39Sopenharmony_ci * loading of fallbacks. Otherwise a misconfiguration could mean the 259e1051a39Sopenharmony_ci * intended provider does not get loaded. Subsequent fetches could 260e1051a39Sopenharmony_ci * then fallback to the default provider - which may be the wrong 261e1051a39Sopenharmony_ci * thing. 262e1051a39Sopenharmony_ci */ 263e1051a39Sopenharmony_ci if (!ossl_provider_disable_fallback_loading(libctx)) { 264e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(pcgbl->lock); 265e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); 266e1051a39Sopenharmony_ci return 0; 267e1051a39Sopenharmony_ci } 268e1051a39Sopenharmony_ci prov = ossl_provider_find(libctx, name, 1); 269e1051a39Sopenharmony_ci if (prov == NULL) 270e1051a39Sopenharmony_ci prov = ossl_provider_new(libctx, name, NULL, 1); 271e1051a39Sopenharmony_ci if (prov == NULL) { 272e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(pcgbl->lock); 273e1051a39Sopenharmony_ci if (soft) 274e1051a39Sopenharmony_ci ERR_clear_error(); 275e1051a39Sopenharmony_ci return 0; 276e1051a39Sopenharmony_ci } 277e1051a39Sopenharmony_ci 278e1051a39Sopenharmony_ci if (path != NULL) 279e1051a39Sopenharmony_ci ossl_provider_set_module_path(prov, path); 280e1051a39Sopenharmony_ci 281e1051a39Sopenharmony_ci ok = provider_conf_params(prov, NULL, NULL, value, cnf); 282e1051a39Sopenharmony_ci 283e1051a39Sopenharmony_ci if (ok > 0) { 284e1051a39Sopenharmony_ci if (!ossl_provider_activate(prov, 1, 0)) { 285e1051a39Sopenharmony_ci ok = 0; 286e1051a39Sopenharmony_ci } else if (!ossl_provider_add_to_store(prov, &actual, 0)) { 287e1051a39Sopenharmony_ci ossl_provider_deactivate(prov, 1); 288e1051a39Sopenharmony_ci ok = 0; 289e1051a39Sopenharmony_ci } else if (actual != prov 290e1051a39Sopenharmony_ci && !ossl_provider_activate(actual, 1, 0)) { 291e1051a39Sopenharmony_ci ossl_provider_free(actual); 292e1051a39Sopenharmony_ci ok = 0; 293e1051a39Sopenharmony_ci } else { 294e1051a39Sopenharmony_ci if (pcgbl->activated_providers == NULL) 295e1051a39Sopenharmony_ci pcgbl->activated_providers = sk_OSSL_PROVIDER_new_null(); 296e1051a39Sopenharmony_ci if (pcgbl->activated_providers == NULL 297e1051a39Sopenharmony_ci || !sk_OSSL_PROVIDER_push(pcgbl->activated_providers, 298e1051a39Sopenharmony_ci actual)) { 299e1051a39Sopenharmony_ci ossl_provider_deactivate(actual, 1); 300e1051a39Sopenharmony_ci ossl_provider_free(actual); 301e1051a39Sopenharmony_ci ok = 0; 302e1051a39Sopenharmony_ci } else { 303e1051a39Sopenharmony_ci ok = 1; 304e1051a39Sopenharmony_ci } 305e1051a39Sopenharmony_ci } 306e1051a39Sopenharmony_ci } 307e1051a39Sopenharmony_ci if (ok <= 0) 308e1051a39Sopenharmony_ci ossl_provider_free(prov); 309e1051a39Sopenharmony_ci } 310e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(pcgbl->lock); 311e1051a39Sopenharmony_ci } else { 312e1051a39Sopenharmony_ci OSSL_PROVIDER_INFO entry; 313e1051a39Sopenharmony_ci 314e1051a39Sopenharmony_ci memset(&entry, 0, sizeof(entry)); 315e1051a39Sopenharmony_ci ok = 1; 316e1051a39Sopenharmony_ci if (name != NULL) { 317e1051a39Sopenharmony_ci entry.name = OPENSSL_strdup(name); 318e1051a39Sopenharmony_ci if (entry.name == NULL) { 319e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 320e1051a39Sopenharmony_ci ok = 0; 321e1051a39Sopenharmony_ci } 322e1051a39Sopenharmony_ci } 323e1051a39Sopenharmony_ci if (ok && path != NULL) { 324e1051a39Sopenharmony_ci entry.path = OPENSSL_strdup(path); 325e1051a39Sopenharmony_ci if (entry.path == NULL) { 326e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 327e1051a39Sopenharmony_ci ok = 0; 328e1051a39Sopenharmony_ci } 329e1051a39Sopenharmony_ci } 330e1051a39Sopenharmony_ci if (ok) 331e1051a39Sopenharmony_ci ok = provider_conf_params(NULL, &entry, NULL, value, cnf); 332e1051a39Sopenharmony_ci if (ok >= 1 && (entry.path != NULL || entry.parameters != NULL)) { 333e1051a39Sopenharmony_ci ok = ossl_provider_info_add_to_store(libctx, &entry); 334e1051a39Sopenharmony_ci added = 1; 335e1051a39Sopenharmony_ci } 336e1051a39Sopenharmony_ci if (added == 0) 337e1051a39Sopenharmony_ci ossl_provider_info_clear(&entry); 338e1051a39Sopenharmony_ci } 339e1051a39Sopenharmony_ci 340e1051a39Sopenharmony_ci /* 341e1051a39Sopenharmony_ci * Provider activation returns a tristate: 342e1051a39Sopenharmony_ci * 1 for successful activation 343e1051a39Sopenharmony_ci * 0 for non-fatal activation failure 344e1051a39Sopenharmony_ci * < 0 for fatal activation failure 345e1051a39Sopenharmony_ci * We return success (1) for activation, (1) for non-fatal activation 346e1051a39Sopenharmony_ci * failure, and (0) for fatal activation failure 347e1051a39Sopenharmony_ci */ 348e1051a39Sopenharmony_ci return ok >= 0; 349e1051a39Sopenharmony_ci} 350e1051a39Sopenharmony_ci 351e1051a39Sopenharmony_cistatic int provider_conf_init(CONF_IMODULE *md, const CONF *cnf) 352e1051a39Sopenharmony_ci{ 353e1051a39Sopenharmony_ci STACK_OF(CONF_VALUE) *elist; 354e1051a39Sopenharmony_ci CONF_VALUE *cval; 355e1051a39Sopenharmony_ci int i; 356e1051a39Sopenharmony_ci 357e1051a39Sopenharmony_ci OSSL_TRACE1(CONF, "Loading providers module: section %s\n", 358e1051a39Sopenharmony_ci CONF_imodule_get_value(md)); 359e1051a39Sopenharmony_ci 360e1051a39Sopenharmony_ci /* Value is a section containing PROVIDERs to configure */ 361e1051a39Sopenharmony_ci elist = NCONF_get_section(cnf, CONF_imodule_get_value(md)); 362e1051a39Sopenharmony_ci 363e1051a39Sopenharmony_ci if (!elist) { 364e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_SECTION_ERROR); 365e1051a39Sopenharmony_ci return 0; 366e1051a39Sopenharmony_ci } 367e1051a39Sopenharmony_ci 368e1051a39Sopenharmony_ci for (i = 0; i < sk_CONF_VALUE_num(elist); i++) { 369e1051a39Sopenharmony_ci cval = sk_CONF_VALUE_value(elist, i); 370e1051a39Sopenharmony_ci if (!provider_conf_load(NCONF_get0_libctx((CONF *)cnf), 371e1051a39Sopenharmony_ci cval->name, cval->value, cnf)) 372e1051a39Sopenharmony_ci return 0; 373e1051a39Sopenharmony_ci } 374e1051a39Sopenharmony_ci 375e1051a39Sopenharmony_ci return 1; 376e1051a39Sopenharmony_ci} 377e1051a39Sopenharmony_ci 378e1051a39Sopenharmony_civoid ossl_provider_add_conf_module(void) 379e1051a39Sopenharmony_ci{ 380e1051a39Sopenharmony_ci OSSL_TRACE(CONF, "Adding config module 'providers'\n"); 381e1051a39Sopenharmony_ci CONF_module_add("providers", provider_conf_init, NULL); 382e1051a39Sopenharmony_ci} 383