#include "config.h"
#include "CurlSSLHandle.h"
#if USE(CURL)
#if NEED_OPENSSL_THREAD_SUPPORT && OS(WINDOWS)
#include <wtf/Threading.h>
#endif
namespace WebCore {
CurlSSLHandle::CurlSSLHandle()
{
#if NEED_OPENSSL_THREAD_SUPPORT
ThreadSupport::setup();
#endif
platformInitialize();
}
void CurlSSLHandle::setCACertPath(String&& caCertPath)
{
RELEASE_ASSERT(!caCertPath.isEmpty());
m_caCertInfo = WTFMove(caCertPath);
}
void CurlSSLHandle::setCACertData(CertificateInfo::Certificate&& caCertData)
{
RELEASE_ASSERT(!caCertData.isEmpty());
m_caCertInfo = WTFMove(caCertData);
}
void CurlSSLHandle::clearCACertInfo()
{
m_caCertInfo = WTF::Monostate { };
}
void CurlSSLHandle::allowAnyHTTPSCertificatesForHost(const String& host)
{
LockHolder mutex(m_allowedHostsLock);
m_allowedHosts.addVoid(host);
}
bool CurlSSLHandle::canIgnoreAnyHTTPSCertificatesForHost(const String& host) const
{
LockHolder mutex(m_allowedHostsLock);
return m_allowedHosts.contains(host);
}
void CurlSSLHandle::setClientCertificateInfo(const String& hostName, const String& certificate, const String& key)
{
LockHolder mutex(m_allowedClientHostsLock);
m_allowedClientHosts.set(hostName, ClientCertificate { certificate, key });
}
Optional<CurlSSLHandle::ClientCertificate> CurlSSLHandle::getSSLClientCertificate(const String& hostName) const
{
LockHolder mutex(m_allowedClientHostsLock);
auto it = m_allowedClientHosts.find(hostName);
if (it == m_allowedClientHosts.end())
return WTF::nullopt;
return it->value;
}
#if NEED_OPENSSL_THREAD_SUPPORT
void CurlSSLHandle::ThreadSupport::setup()
{
static std::once_flag onceFlag;
std::call_once(onceFlag, [] {
singleton();
});
}
CurlSSLHandle::ThreadSupport::ThreadSupport()
{
CRYPTO_set_locking_callback(lockingCallback);
#if OS(WINDOWS)
CRYPTO_THREADID_set_callback(threadIdCallback);
#endif
}
void CurlSSLHandle::ThreadSupport::lockingCallback(int mode, int type, const char*, int)
{
RELEASE_ASSERT(type >= 0 && type < CRYPTO_NUM_LOCKS);
auto& locker = ThreadSupport::singleton();
if (mode & CRYPTO_LOCK)
locker.lock(type);
else
locker.unlock(type);
}
#if OS(WINDOWS)
void CurlSSLHandle::ThreadSupport::threadIdCallback(CRYPTO_THREADID* threadId)
{
CRYPTO_THREADID_set_numeric(threadId, static_cast<unsigned long>(Thread::currentID()));
}
#endif
#endif
}
#endif