app_provider.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * Copyright 2020-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. #include "apps.h"
  10. #include <string.h>
  11. #include <openssl/err.h>
  12. #include <openssl/provider.h>
  13. #include <openssl/safestack.h>
  14. /* Non-zero if any of the provider options have been seen */
  15. static int provider_option_given = 0;
  16. DEFINE_STACK_OF(OSSL_PROVIDER)
  17. /*
  18. * See comments in opt_verify for explanation of this.
  19. */
  20. enum prov_range { OPT_PROV_ENUM };
  21. static STACK_OF(OSSL_PROVIDER) *app_providers = NULL;
  22. static void provider_free(OSSL_PROVIDER *prov)
  23. {
  24. OSSL_PROVIDER_unload(prov);
  25. }
  26. int app_provider_load(OSSL_LIB_CTX *libctx, const char *provider_name)
  27. {
  28. OSSL_PROVIDER *prov;
  29. prov = OSSL_PROVIDER_load(libctx, provider_name);
  30. if (prov == NULL) {
  31. opt_printf_stderr("%s: unable to load provider %s\n"
  32. "Hint: use -provider-path option or OPENSSL_MODULES environment variable.\n",
  33. opt_getprog(), provider_name);
  34. ERR_print_errors(bio_err);
  35. return 0;
  36. }
  37. if (app_providers == NULL)
  38. app_providers = sk_OSSL_PROVIDER_new_null();
  39. if (app_providers == NULL
  40. || !sk_OSSL_PROVIDER_push(app_providers, prov)) {
  41. app_providers_cleanup();
  42. return 0;
  43. }
  44. return 1;
  45. }
  46. void app_providers_cleanup(void)
  47. {
  48. sk_OSSL_PROVIDER_pop_free(app_providers, provider_free);
  49. app_providers = NULL;
  50. }
  51. static int opt_provider_path(const char *path)
  52. {
  53. if (path != NULL && *path == '\0')
  54. path = NULL;
  55. return OSSL_PROVIDER_set_default_search_path(app_get0_libctx(), path);
  56. }
  57. int opt_provider(int opt)
  58. {
  59. const int given = provider_option_given;
  60. provider_option_given = 1;
  61. switch ((enum prov_range)opt) {
  62. case OPT_PROV__FIRST:
  63. case OPT_PROV__LAST:
  64. return 1;
  65. case OPT_PROV_PROVIDER:
  66. return app_provider_load(app_get0_libctx(), opt_arg());
  67. case OPT_PROV_PROVIDER_PATH:
  68. return opt_provider_path(opt_arg());
  69. case OPT_PROV_PROPQUERY:
  70. return app_set_propq(opt_arg());
  71. }
  72. /* Should never get here but if we do, undo what we did earlier */
  73. provider_option_given = given;
  74. return 0;
  75. }
  76. int opt_provider_option_given(void)
  77. {
  78. return provider_option_given;
  79. }