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