123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- /**
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * SPDX-License-Identifier: Apache-2.0.
- */
- #include <aws/crt/Api.h>
- #include <aws/crt/StlAllocator.h>
- #include <aws/crt/external/cJSON.h>
- #include <aws/crt/io/TlsOptions.h>
- #include <aws/auth/auth.h>
- #include <aws/common/ref_count.h>
- #include <aws/event-stream/event_stream.h>
- #include <aws/http/http.h>
- #include <aws/mqtt/mqtt.h>
- #include <aws/s3/s3.h>
- #include <thread>
- namespace Aws
- {
- namespace Crt
- {
- static Crypto::CreateHashCallback s_BYOCryptoNewMD5Callback;
- static Crypto::CreateHashCallback s_BYOCryptoNewSHA256Callback;
- static Crypto::CreateHMACCallback s_BYOCryptoNewSHA256HMACCallback;
- static Io::NewClientTlsHandlerCallback s_BYOCryptoNewClientTlsHandlerCallback;
- static Io::NewTlsContextImplCallback s_BYOCryptoNewTlsContextImplCallback;
- static Io::DeleteTlsContextImplCallback s_BYOCryptoDeleteTlsContextImplCallback;
- static Io::IsTlsAlpnSupportedCallback s_BYOCryptoIsTlsAlpnSupportedCallback;
- Io::ClientBootstrap *ApiHandle::s_static_bootstrap = nullptr;
- Io::EventLoopGroup *ApiHandle::s_static_event_loop_group = nullptr;
- int ApiHandle::s_host_resolver_default_max_hosts = 8;
- Io::HostResolver *ApiHandle::s_static_default_host_resolver = nullptr;
- std::mutex ApiHandle::s_lock_client_bootstrap;
- std::mutex ApiHandle::s_lock_event_loop_group;
- std::mutex ApiHandle::s_lock_default_host_resolver;
- static void *s_cJSONAlloc(size_t sz) { return aws_mem_acquire(ApiAllocator(), sz); }
- static void s_cJSONFree(void *ptr) { return aws_mem_release(ApiAllocator(), ptr); }
- static void s_initApi(Allocator *allocator)
- {
- // sets up the StlAllocator for use.
- g_allocator = allocator;
- aws_mqtt_library_init(allocator);
- aws_s3_library_init(allocator);
- aws_event_stream_library_init(allocator);
- aws_sdkutils_library_init(allocator);
- cJSON_Hooks hooks;
- hooks.malloc_fn = s_cJSONAlloc;
- hooks.free_fn = s_cJSONFree;
- cJSON_InitHooks(&hooks);
- }
- ApiHandle::ApiHandle(Allocator *allocator) noexcept
- : m_logger(), m_shutdownBehavior(ApiHandleShutdownBehavior::Blocking)
- {
- s_initApi(allocator);
- }
- ApiHandle::ApiHandle() noexcept : m_logger(), m_shutdownBehavior(ApiHandleShutdownBehavior::Blocking)
- {
- s_initApi(DefaultAllocator());
- }
- ApiHandle::~ApiHandle()
- {
- ReleaseStaticDefaultClientBootstrap();
- ReleaseStaticDefaultEventLoopGroup();
- ReleaseStaticDefaultHostResolver();
- if (m_shutdownBehavior == ApiHandleShutdownBehavior::Blocking)
- {
- aws_thread_join_all_managed();
- }
- if (aws_logger_get() == &m_logger)
- {
- aws_logger_set(NULL);
- aws_logger_clean_up(&m_logger);
- }
- g_allocator = nullptr;
- aws_s3_library_clean_up();
- aws_mqtt_library_clean_up();
- aws_event_stream_library_clean_up();
- aws_sdkutils_library_clean_up();
- s_BYOCryptoNewMD5Callback = nullptr;
- s_BYOCryptoNewSHA256Callback = nullptr;
- s_BYOCryptoNewSHA256HMACCallback = nullptr;
- s_BYOCryptoNewClientTlsHandlerCallback = nullptr;
- s_BYOCryptoNewTlsContextImplCallback = nullptr;
- s_BYOCryptoDeleteTlsContextImplCallback = nullptr;
- s_BYOCryptoIsTlsAlpnSupportedCallback = nullptr;
- }
- void ApiHandle::InitializeLogging(Aws::Crt::LogLevel level, const char *filename)
- {
- struct aws_logger_standard_options options;
- AWS_ZERO_STRUCT(options);
- options.level = (enum aws_log_level)level;
- options.filename = filename;
- InitializeLoggingCommon(options);
- }
- void ApiHandle::InitializeLogging(Aws::Crt::LogLevel level, FILE *fp)
- {
- struct aws_logger_standard_options options;
- AWS_ZERO_STRUCT(options);
- options.level = (enum aws_log_level)level;
- options.file = fp;
- InitializeLoggingCommon(options);
- }
- void ApiHandle::InitializeLoggingCommon(struct aws_logger_standard_options &options)
- {
- if (aws_logger_get() == &m_logger)
- {
- aws_logger_set(NULL);
- aws_logger_clean_up(&m_logger);
- if (options.level == AWS_LL_NONE)
- {
- AWS_ZERO_STRUCT(m_logger);
- return;
- }
- }
- if (aws_logger_init_standard(&m_logger, ApiAllocator(), &options))
- {
- return;
- }
- aws_logger_set(&m_logger);
- }
- void ApiHandle::SetShutdownBehavior(ApiHandleShutdownBehavior behavior) { m_shutdownBehavior = behavior; }
- #if BYO_CRYPTO
- static struct aws_hash *s_MD5New(struct aws_allocator *allocator)
- {
- if (!s_BYOCryptoNewMD5Callback)
- {
- AWS_LOGF_ERROR(
- AWS_LS_IO_TLS, "Must call ApiHandle::SetBYOCryptoNewMD5Callback() before MD5 hash can be created");
- aws_raise_error(AWS_ERROR_UNIMPLEMENTED);
- return nullptr;
- }
- auto hash = s_BYOCryptoNewMD5Callback(AWS_MD5_LEN, allocator);
- if (!hash)
- {
- return nullptr;
- }
- return hash->SeatForCInterop(hash);
- }
- void ApiHandle::SetBYOCryptoNewMD5Callback(Crypto::CreateHashCallback &&callback)
- {
- s_BYOCryptoNewMD5Callback = std::move(callback);
- aws_set_md5_new_fn(s_MD5New);
- }
- static struct aws_hash *s_Sha256New(struct aws_allocator *allocator)
- {
- if (!s_BYOCryptoNewSHA256Callback)
- {
- AWS_LOGF_ERROR(
- AWS_LS_IO_TLS,
- "Must call ApiHandle::SetBYOCryptoNewSHA256Callback() before SHA256 hash can be created");
- aws_raise_error(AWS_ERROR_UNIMPLEMENTED);
- return nullptr;
- }
- auto hash = s_BYOCryptoNewSHA256Callback(AWS_SHA256_LEN, allocator);
- if (!hash)
- {
- return nullptr;
- }
- return hash->SeatForCInterop(hash);
- }
- void ApiHandle::SetBYOCryptoNewSHA256Callback(Crypto::CreateHashCallback &&callback)
- {
- s_BYOCryptoNewSHA256Callback = std::move(callback);
- aws_set_sha256_new_fn(s_Sha256New);
- }
- static struct aws_hmac *s_sha256HMACNew(struct aws_allocator *allocator, const struct aws_byte_cursor *secret)
- {
- if (!s_BYOCryptoNewSHA256HMACCallback)
- {
- AWS_LOGF_ERROR(
- AWS_LS_IO_TLS,
- "Must call ApiHandle::SetBYOCryptoNewSHA256HMACCallback() before SHA256 HMAC can be created");
- aws_raise_error(AWS_ERROR_UNIMPLEMENTED);
- return nullptr;
- }
- auto hmac = s_BYOCryptoNewSHA256HMACCallback(AWS_SHA256_HMAC_LEN, *secret, allocator);
- if (!hmac)
- {
- return nullptr;
- }
- return hmac->SeatForCInterop(hmac);
- }
- void ApiHandle::SetBYOCryptoNewSHA256HMACCallback(Crypto::CreateHMACCallback &&callback)
- {
- s_BYOCryptoNewSHA256HMACCallback = std::move(callback);
- aws_set_sha256_hmac_new_fn(s_sha256HMACNew);
- }
- static struct aws_channel_handler *s_NewClientTlsHandler(
- struct aws_allocator *allocator,
- struct aws_tls_connection_options *options,
- struct aws_channel_slot *slot,
- void *)
- {
- if (!s_BYOCryptoNewClientTlsHandlerCallback)
- {
- AWS_LOGF_ERROR(
- AWS_LS_IO_TLS,
- "Must call ApiHandle::SetBYOCryptoClientTlsCallback() before client TLS handler can be created");
- aws_raise_error(AWS_ERROR_UNIMPLEMENTED);
- return nullptr;
- }
- auto clientHandlerSelfReferencing = s_BYOCryptoNewClientTlsHandlerCallback(slot, *options, allocator);
- if (!clientHandlerSelfReferencing)
- {
- return nullptr;
- }
- return clientHandlerSelfReferencing->SeatForCInterop(clientHandlerSelfReferencing);
- }
- static int s_ClientTlsHandlerStartNegotiation(struct aws_channel_handler *handler, void *)
- {
- auto *clientHandler = reinterpret_cast<Io::ClientTlsChannelHandler *>(handler->impl);
- if (clientHandler->ChannelsThreadIsCallersThread())
- {
- clientHandler->StartNegotiation();
- }
- else
- {
- clientHandler->ScheduleTask([clientHandler](Io::TaskStatus) { clientHandler->StartNegotiation(); });
- }
- return AWS_OP_SUCCESS;
- }
- void ApiHandle::SetBYOCryptoClientTlsCallback(Io::NewClientTlsHandlerCallback &&callback)
- {
- s_BYOCryptoNewClientTlsHandlerCallback = std::move(callback);
- struct aws_tls_byo_crypto_setup_options setupOptions;
- setupOptions.new_handler_fn = s_NewClientTlsHandler;
- setupOptions.start_negotiation_fn = s_ClientTlsHandlerStartNegotiation;
- setupOptions.user_data = nullptr;
- aws_tls_byo_crypto_set_client_setup_options(&setupOptions);
- }
- void ApiHandle::SetBYOCryptoTlsContextCallbacks(
- Io::NewTlsContextImplCallback &&newCallback,
- Io::DeleteTlsContextImplCallback &&deleteCallback,
- Io::IsTlsAlpnSupportedCallback &&alpnCallback)
- {
- s_BYOCryptoNewTlsContextImplCallback = newCallback;
- s_BYOCryptoDeleteTlsContextImplCallback = deleteCallback;
- s_BYOCryptoIsTlsAlpnSupportedCallback = alpnCallback;
- }
- #else // BYO_CRYPTO
- void ApiHandle::SetBYOCryptoNewMD5Callback(Crypto::CreateHashCallback &&)
- {
- AWS_LOGF_WARN(AWS_LS_IO_TLS, "SetBYOCryptoNewMD5Callback() has no effect unless compiled with BYO_CRYPTO");
- }
- void ApiHandle::SetBYOCryptoNewSHA256Callback(Crypto::CreateHashCallback &&)
- {
- AWS_LOGF_WARN(
- AWS_LS_IO_TLS, "SetBYOCryptoNewSHA256Callback() has no effect unless compiled with BYO_CRYPTO");
- }
- void ApiHandle::SetBYOCryptoNewSHA256HMACCallback(Crypto::CreateHMACCallback &&)
- {
- AWS_LOGF_WARN(
- AWS_LS_IO_TLS, "SetBYOCryptoNewSHA256HMACCallback() has no effect unless compiled with BYO_CRYPTO");
- }
- void ApiHandle::SetBYOCryptoClientTlsCallback(Io::NewClientTlsHandlerCallback &&)
- {
- AWS_LOGF_WARN(
- AWS_LS_IO_TLS, "SetBYOCryptoClientTlsCallback() has no effect unless compiled with BYO_CRYPTO");
- }
- void ApiHandle::SetBYOCryptoTlsContextCallbacks(
- Io::NewTlsContextImplCallback &&,
- Io::DeleteTlsContextImplCallback &&,
- Io::IsTlsAlpnSupportedCallback &&)
- {
- AWS_LOGF_WARN(
- AWS_LS_IO_TLS, "SetBYOCryptoClientTlsCallback() has no effect unless compiled with BYO_CRYPTO");
- }
- #endif // BYO_CRYPTO
- Io::ClientBootstrap *ApiHandle::GetOrCreateStaticDefaultClientBootstrap()
- {
- std::lock_guard<std::mutex> lock(s_lock_client_bootstrap);
- if (s_static_bootstrap == nullptr)
- {
- s_static_bootstrap = Aws::Crt::New<Io::ClientBootstrap>(
- ApiAllocator(), *GetOrCreateStaticDefaultEventLoopGroup(), *GetOrCreateStaticDefaultHostResolver());
- }
- return s_static_bootstrap;
- }
- Io::EventLoopGroup *ApiHandle::GetOrCreateStaticDefaultEventLoopGroup()
- {
- std::lock_guard<std::mutex> lock(s_lock_event_loop_group);
- if (s_static_event_loop_group == nullptr)
- {
- s_static_event_loop_group = Aws::Crt::New<Io::EventLoopGroup>(ApiAllocator(), (uint16_t)0);
- }
- return s_static_event_loop_group;
- }
- Io::HostResolver *ApiHandle::GetOrCreateStaticDefaultHostResolver()
- {
- std::lock_guard<std::mutex> lock(s_lock_default_host_resolver);
- if (s_static_default_host_resolver == nullptr)
- {
- s_static_default_host_resolver = Aws::Crt::New<Io::DefaultHostResolver>(
- ApiAllocator(), *GetOrCreateStaticDefaultEventLoopGroup(), 1, s_host_resolver_default_max_hosts);
- }
- return s_static_default_host_resolver;
- }
- void ApiHandle::ReleaseStaticDefaultClientBootstrap()
- {
- std::lock_guard<std::mutex> lock(s_lock_client_bootstrap);
- if (s_static_bootstrap != nullptr)
- {
- Aws::Crt::Delete(s_static_bootstrap, ApiAllocator());
- s_static_bootstrap = nullptr;
- }
- }
- void ApiHandle::ReleaseStaticDefaultEventLoopGroup()
- {
- std::lock_guard<std::mutex> lock(s_lock_event_loop_group);
- if (s_static_event_loop_group != nullptr)
- {
- Aws::Crt::Delete(s_static_event_loop_group, ApiAllocator());
- s_static_event_loop_group = nullptr;
- }
- }
- void ApiHandle::ReleaseStaticDefaultHostResolver()
- {
- std::lock_guard<std::mutex> lock(s_lock_default_host_resolver);
- if (s_static_default_host_resolver != nullptr)
- {
- Aws::Crt::Delete(s_static_default_host_resolver, ApiAllocator());
- s_static_default_host_resolver = nullptr;
- }
- }
- const Io::NewTlsContextImplCallback &ApiHandle::GetBYOCryptoNewTlsContextImplCallback()
- {
- return s_BYOCryptoNewTlsContextImplCallback;
- }
- const Io::DeleteTlsContextImplCallback &ApiHandle::GetBYOCryptoDeleteTlsContextImplCallback()
- {
- return s_BYOCryptoDeleteTlsContextImplCallback;
- }
- const Io::IsTlsAlpnSupportedCallback &ApiHandle::GetBYOCryptoIsTlsAlpnSupportedCallback()
- {
- return s_BYOCryptoIsTlsAlpnSupportedCallback;
- }
- const char *ErrorDebugString(int error) noexcept { return aws_error_debug_str(error); }
- int LastError() noexcept { return aws_last_error(); }
- int LastErrorOrUnknown() noexcept
- {
- int last_error = aws_last_error();
- if (last_error == AWS_ERROR_SUCCESS)
- {
- last_error = AWS_ERROR_UNKNOWN;
- }
- return last_error;
- }
- } // namespace Crt
- } // namespace Aws
|