core_fetch.c 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * Copyright 2019 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 <stddef.h>
  10. #include <openssl/core.h>
  11. #include "internal/cryptlib.h"
  12. #include "internal/core.h"
  13. #include "internal/property.h"
  14. #include "internal/provider.h"
  15. struct construct_data_st {
  16. OPENSSL_CTX *libctx;
  17. OSSL_METHOD_STORE *store;
  18. int operation_id;
  19. int force_store;
  20. OSSL_METHOD_CONSTRUCT_METHOD *mcm;
  21. void *mcm_data;
  22. };
  23. static void ossl_method_construct_this(OSSL_PROVIDER *provider,
  24. const OSSL_ALGORITHM *algo,
  25. int no_store, void *cbdata)
  26. {
  27. struct construct_data_st *data = cbdata;
  28. void *method = NULL;
  29. if ((method = data->mcm->construct(algo->algorithm_names,
  30. algo->implementation, provider,
  31. data->mcm_data)) == NULL)
  32. return;
  33. /*
  34. * Note regarding putting the method in stores:
  35. *
  36. * we don't need to care if it actually got in or not here.
  37. * If it didn't get in, it will simply not be available when
  38. * ossl_method_construct() tries to get it from the store.
  39. *
  40. * It is *expected* that the put function increments the refcnt
  41. * of the passed method.
  42. */
  43. if (data->force_store || !no_store) {
  44. /*
  45. * If we haven't been told not to store,
  46. * add to the global store
  47. */
  48. data->mcm->put(data->libctx, NULL, method, provider,
  49. data->operation_id, algo->algorithm_names,
  50. algo->property_definition, data->mcm_data);
  51. }
  52. data->mcm->put(data->libctx, data->store, method, provider,
  53. data->operation_id, algo->algorithm_names,
  54. algo->property_definition, data->mcm_data);
  55. /* refcnt-- because we're dropping the reference */
  56. data->mcm->destruct(method, data->mcm_data);
  57. }
  58. void *ossl_method_construct(OPENSSL_CTX *libctx, int operation_id,
  59. int force_store,
  60. OSSL_METHOD_CONSTRUCT_METHOD *mcm, void *mcm_data)
  61. {
  62. void *method = NULL;
  63. if ((method = mcm->get(libctx, NULL, mcm_data)) == NULL) {
  64. struct construct_data_st cbdata;
  65. /*
  66. * We have a temporary store to be able to easily search among new
  67. * items, or items that should find themselves in the global store.
  68. */
  69. if ((cbdata.store = mcm->alloc_tmp_store(libctx)) == NULL)
  70. goto fin;
  71. cbdata.libctx = libctx;
  72. cbdata.operation_id = operation_id;
  73. cbdata.force_store = force_store;
  74. cbdata.mcm = mcm;
  75. cbdata.mcm_data = mcm_data;
  76. ossl_algorithm_do_all(libctx, operation_id, NULL,
  77. ossl_method_construct_this, &cbdata);
  78. method = mcm->get(libctx, cbdata.store, mcm_data);
  79. mcm->dealloc_tmp_store(cbdata.store);
  80. }
  81. fin:
  82. return method;
  83. }