Rocket.Chat.ReactNative/ios/Pods/Flipper-Folly/folly/ssl/Init.cpp

109 lines
2.9 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <folly/ssl/Init.h>
#include <mutex>
#include <folly/portability/OpenSSL.h>
#include <folly/ssl/detail/OpenSSLThreading.h>
#include <glog/logging.h>
namespace folly {
namespace ssl {
namespace {
bool initialized_ = false;
std::mutex& initMutex() {
static std::mutex m;
return m;
}
void initializeOpenSSLLocked() {
if (initialized_) {
return;
}
if (OPENSSL_init_ssl(0, nullptr) != 1) {
// Fail early if we fail to initialize OpenSSL. Ignoring this means that
// future OpenSSL methods may segfault, since there is an implicit
// precondition that initialization properly initializes internal OpenSSL
// pointers to global resources.
throw std::runtime_error("Failed to initialize OpenSSL.");
}
// OpenSSL implicitly seeds its RNG since 1.1.0, so this call is unnecessary
// and is only here for compatibility with older versions of OpenSSL.
#if !(FOLLY_OPENSSL_IS_110)
if (RAND_poll() != 1) {
// Similarly, if we fail to seed the RNG, future crypto operations
// may no longer be safe to use; fail fast and hard here.
throw std::runtime_error("Failed to initialize OpenSSL RNG.");
}
#endif
initialized_ = true;
}
void cleanupOpenSSLLocked() {
if (!initialized_) {
return;
}
OPENSSL_cleanup();
initialized_ = false;
}
} // namespace
void init() {
std::lock_guard<std::mutex> g(initMutex());
initializeOpenSSLLocked();
}
void cleanup() {
std::lock_guard<std::mutex> g(initMutex());
cleanupOpenSSLLocked();
}
void markInitialized() {
std::lock_guard<std::mutex> g(initMutex());
initialized_ = true;
}
void setLockTypesAndInit(LockTypeMapping inLockTypes) {
std::lock_guard<std::mutex> g(initMutex());
CHECK(!initialized_) << "OpenSSL is already initialized";
detail::setLockTypes(std::move(inLockTypes));
initializeOpenSSLLocked();
}
void setLockTypes(LockTypeMapping inLockTypes) {
std::lock_guard<std::mutex> g(initMutex());
if (initialized_) {
// We set the locks on initialization, so if we are already initialized
// this would have no affect.
LOG(INFO) << "Ignoring setSSLLockTypes after initialization";
return;
}
detail::setLockTypes(std::move(inLockTypes));
}
bool isLockDisabled(int lockId) {
return detail::isSSLLockDisabled(lockId);
}
} // namespace ssl
} // namespace folly