From 9a3a35214284265e19fad3a74f758fd254f5c8fb Mon Sep 17 00:00:00 2001 From: Nimetu Date: Tue, 4 Jul 2017 00:34:11 +0300 Subject: [PATCH] Changed: Refactor curl certificate loading (issue #314) --HG-- branch : develop --- code/nel/include/nel/gui/curl_certificates.h | 35 ++++++ code/nel/src/gui/curl_certificates.cpp | 123 +++++++++++++++++++ code/nel/src/gui/group_html.cpp | 93 +------------- 3 files changed, 161 insertions(+), 90 deletions(-) create mode 100644 code/nel/include/nel/gui/curl_certificates.h create mode 100644 code/nel/src/gui/curl_certificates.cpp diff --git a/code/nel/include/nel/gui/curl_certificates.h b/code/nel/include/nel/gui/curl_certificates.h new file mode 100644 index 000000000..021b13360 --- /dev/null +++ b/code/nel/include/nel/gui/curl_certificates.h @@ -0,0 +1,35 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef CL_CURL_CERTIFICATES_HTML_H +#define CL_CURL_CERTIFICATES_HTML_H + +#include + +#include "nel/misc/types_nl.h" + +namespace NLGUI +{ +#if defined(NL_OS_WINDOWS) + class CCurlCertificates { + public: + // cURL SSL certificate loading + static CURLcode sslCtxFunction(CURL *curl, void *sslctx, void *parm); + }; +#endif // NL_OS_WINDOWS + +} // namespace +#endif diff --git a/code/nel/src/gui/curl_certificates.cpp b/code/nel/src/gui/curl_certificates.cpp new file mode 100644 index 000000000..6cf34c8b8 --- /dev/null +++ b/code/nel/src/gui/curl_certificates.cpp @@ -0,0 +1,123 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +//#include + +#include "stdpch.h" +#include "nel/gui/curl_certificates.h" + +#include +#include + +#if defined(NL_OS_WINDOWS) +#pragma comment(lib, "crypt32.lib") +#pragma comment(lib, "cryptui.lib") +#endif + +using namespace std; +using namespace NLMISC; + +#ifdef DEBUG_NEW +#define new DEBUG_NEW +#endif + +namespace NLGUI +{ +#if defined(NL_OS_WINDOWS) + static std::vector x509CertList; + + // + // x509CertList lifetime manager + // + class SX509Certificates { + public: + SX509Certificates() + { + curl_version_info_data *data; + data = curl_version_info(CURLVERSION_NOW); + if (!(data && data->features & CURL_VERSION_SSPI)) + { + addCertificatesFrom("CA"); + addCertificatesFrom("AuthRoot"); + addCertificatesFrom("ROOT"); + } + } + + ~SX509Certificates() + { + for (uint i = 0; i < x509CertList.size(); ++i) + { + X509_free(x509CertList[i]); + } + + x509CertList.clear(); + } + + void addCertificatesFrom(LPCSTR root) + { + HCERTSTORE hStore; + PCCERT_CONTEXT pContext = NULL; + X509 *x509; + hStore = CertOpenSystemStore(NULL, root); + if (hStore) + { + while (pContext = CertEnumCertificatesInStore(hStore, pContext)) + { + x509 = NULL; + x509 = d2i_X509(NULL, (const unsigned char **)&pContext->pbCertEncoded, pContext->cbCertEncoded); + if (x509) + { + x509CertList.push_back(x509); + } + } + CertFreeCertificateContext(pContext); + CertCloseStore(hStore, 0); + } + + // this is called before debug context is set and log ends up in log.log + //nlinfo("Loaded %d certificates from '%s' certificate store", List.size(), root); + } + }; + + /// this will be initialized on startup and cleared on exit + static SX509Certificates x509CertListManager; + + // *************************************************************************** + // static + CURLcode CCurlCertificates::sslCtxFunction(CURL *curl, void *sslctx, void *parm) + { + if (x509CertList.size() > 0) + { + SSL_CTX *ctx = (SSL_CTX*)sslctx; + X509_STORE *x509store = SSL_CTX_get_cert_store(ctx); + if (x509store) + { + for (uint i = 0; i < x509CertList.size(); ++i) + { + X509_STORE_add_cert(x509store, x509CertList[i]); + } + } + else + { + nlwarning("SSL_CTX_get_cert_store returned NULL"); + } + } + return CURLE_OK; + } +#endif // NL_OS_WINDOWS + +}// namespace + diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index ec20d58d2..e99149cec 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -46,16 +46,7 @@ #include "nel/misc/big_file.h" #include "nel/gui/url_parser.h" #include "nel/gui/http_cache.h" - -#if defined(NL_OS_WINDOWS) -#include -#include -#include - -#pragma comment(lib, "crypt32.lib") -#pragma comment(lib, "cryptui.lib") -#endif - +#include "nel/gui/curl_certificates.h" using namespace std; using namespace NLMISC; @@ -80,84 +71,6 @@ namespace NLGUI CGroupHTML::SWebOptions CGroupHTML::options; -#if defined(NL_OS_WINDOWS) - class SX509Certificates { - public: - SX509Certificates() - { - curl_version_info_data *data; - data = curl_version_info(CURLVERSION_NOW); - if (!(data && data->features & CURL_VERSION_SSPI)) - { - addCertificatesFrom("CA"); - addCertificatesFrom("AuthRoot"); - addCertificatesFrom("ROOT"); - } - } - - ~SX509Certificates() - { - for (uint i = 0; i < List.size(); ++i) - { - X509_free(List[i]); - } - - List.clear(); - } - - void addCertificatesFrom(LPCSTR root) - { - HCERTSTORE hStore; - PCCERT_CONTEXT pContext = NULL; - X509 *x509; - hStore = CertOpenSystemStore(NULL, root); - if (hStore) - { - while (pContext = CertEnumCertificatesInStore(hStore, pContext)) - { - x509 = NULL; - x509 = d2i_X509(NULL, (const unsigned char **)&pContext->pbCertEncoded, pContext->cbCertEncoded); - if (x509) - { - List.push_back(x509); - } - } - CertFreeCertificateContext(pContext); - CertCloseStore(hStore, 0); - } - - // this is called before debug context is set and log ends up in log.log - //nlinfo("Loaded %d certificates from '%s' certificate store", List.size(), root); - } - public: - std::vector List; - }; - - /// this will be initialized on startup and cleared on exit - static SX509Certificates x509CertList; - - static CURLcode ssl_ctx_function(CURL *curl, void *sslctx, void *parm) - { - if (x509CertList.List.size() > 0) - { - SSL_CTX *ctx = (SSL_CTX*)sslctx; - X509_STORE *x509store = SSL_CTX_get_cert_store(ctx); - if (x509store) - { - for (uint i = 0; i < x509CertList.List.size(); ++i) - { - X509_STORE_add_cert(x509store, x509CertList.List[i]); - } - } - else - { - nlwarning("SSL_CTX_get_cert_store returned NULL"); - } - } - return CURLE_OK; - } -#endif - // Active cURL www transfer class CCurlWWWData { @@ -447,7 +360,7 @@ namespace NLGUI // https:// if (toLower(download.url.substr(0, 8)) == "https://") { - curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, &ssl_ctx_function); + curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, &CCurlCertificates::sslCtxFunction); } #endif @@ -5363,7 +5276,7 @@ namespace NLGUI // https:// if (toLower(url.substr(0, 8)) == "https://") { - curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, &ssl_ctx_function); + curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, &CCurlCertificates::sslCtxFunction); } #endif