comparison Core/HttpClient.cpp @ 2025:e7e1858d9504

reorganization
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 20 Jun 2016 13:23:42 +0200
parents 944b255035a0
children 6ea2e264ca50
comparison
equal deleted inserted replaced
2024:944b255035a0 2025:e7e1858d9504
42 #include <boost/algorithm/string/predicate.hpp> 42 #include <boost/algorithm/string/predicate.hpp>
43 #include <boost/thread/mutex.hpp> 43 #include <boost/thread/mutex.hpp>
44 44
45 45
46 #if ORTHANC_PKCS11_ENABLED == 1 46 #if ORTHANC_PKCS11_ENABLED == 1
47 47 # include "Pkcs11.h"
48 #include <openssl/engine.h>
49 #include <libp11.h>
50
51 // Include the "libengine-pkcs11-openssl" from the libp11 package
52 extern "C"
53 {
54 #pragma GCC diagnostic error "-fpermissive"
55 #include <libp11/eng_front.c>
56 }
57
58 #endif 48 #endif
59 49
60 50
61 extern "C" 51 extern "C"
62 { 52 {
95 boost::mutex mutex_; 85 boost::mutex mutex_;
96 bool httpsVerifyPeers_; 86 bool httpsVerifyPeers_;
97 std::string httpsCACertificates_; 87 std::string httpsCACertificates_;
98 std::string proxy_; 88 std::string proxy_;
99 long timeout_; 89 long timeout_;
100 bool pkcs11Initialized_;
101
102 #if ORTHANC_PKCS11_ENABLED == 1
103 static ENGINE* LoadPkcs11Engine()
104 {
105 // This function mimics the "ENGINE_load_dynamic" function from
106 // OpenSSL, in file "crypto/engine/eng_dyn.c"
107
108 ENGINE* engine = ENGINE_new();
109 if (!engine)
110 {
111 LOG(ERROR) << "Cannot create an OpenSSL engine for PKCS11";
112 throw OrthancException(ErrorCode_InternalError);
113 }
114
115 if (!bind_helper(engine) ||
116 !ENGINE_add(engine))
117 {
118 LOG(ERROR) << "Cannot initialize the OpenSSL engine for PKCS11";
119 ENGINE_free(engine);
120 throw OrthancException(ErrorCode_InternalError);
121 }
122
123 // If the "ENGINE_add" worked, it gets a structural
124 // reference. We release our just-created reference.
125 ENGINE_free(engine);
126
127 assert(!strcmp("pkcs11", PKCS11_ENGINE_ID));
128 return ENGINE_by_id(PKCS11_ENGINE_ID);
129 }
130 #endif
131 90
132 GlobalParameters() : 91 GlobalParameters() :
133 httpsVerifyPeers_(true), 92 httpsVerifyPeers_(true),
134 timeout_(0), 93 timeout_(0)
135 pkcs11Initialized_(false)
136 { 94 {
137 } 95 }
138 96
139 public: 97 public:
140 // Singleton pattern 98 // Singleton pattern
190 { 148 {
191 boost::mutex::scoped_lock lock(mutex_); 149 boost::mutex::scoped_lock lock(mutex_);
192 return timeout_; 150 return timeout_;
193 } 151 }
194 152
153 #if ORTHANC_PKCS11_ENABLED == 1
195 bool IsPkcs11Initialized() 154 bool IsPkcs11Initialized()
196 { 155 {
197 boost::mutex::scoped_lock lock(mutex_); 156 boost::mutex::scoped_lock lock(mutex_);
198 return pkcs11Initialized_; 157 return Pkcs11::IsInitialized();
199 } 158 }
200 159
201
202 #if ORTHANC_PKCS11_ENABLED == 1
203 void InitializePkcs11(const std::string& module, 160 void InitializePkcs11(const std::string& module,
204 const std::string& pin, 161 const std::string& pin,
205 bool verbose) 162 bool verbose)
206 { 163 {
207 boost::mutex::scoped_lock lock(mutex_); 164 boost::mutex::scoped_lock lock(mutex_);
208 165 Pkcs11::Initialize(module, pin, verbose);
209 if (pkcs11Initialized_)
210 {
211 LOG(ERROR) << "The PKCS11 engine has already been initialized";
212 throw OrthancException(ErrorCode_BadSequenceOfCalls);
213 }
214
215 if (module.empty() ||
216 !Toolbox::IsRegularFile(module))
217 {
218 LOG(ERROR) << "The PKCS11 module must be a path to one shared library (DLL or .so)";
219 throw OrthancException(ErrorCode_InexistentFile);
220 }
221
222 ENGINE* engine = LoadPkcs11Engine();
223 if (!engine)
224 {
225 LOG(ERROR) << "Cannot create an OpenSSL engine for PKCS11";
226 throw OrthancException(ErrorCode_InternalError);
227 }
228
229 if (!ENGINE_ctrl_cmd_string(engine, "MODULE_PATH", module.c_str(), 0))
230 {
231 LOG(ERROR) << "Cannot configure the OpenSSL dynamic engine for PKCS11";
232 throw OrthancException(ErrorCode_InternalError);
233 }
234
235 if (verbose)
236 {
237 ENGINE_ctrl_cmd_string(engine, "VERBOSE", NULL, 0);
238 }
239
240 if (!pin.empty() &&
241 !ENGINE_ctrl_cmd_string(engine, "PIN", pin.c_str(), 0))
242 {
243 LOG(ERROR) << "Cannot set the PIN code for PKCS11";
244 throw OrthancException(ErrorCode_InternalError);
245 }
246
247 if (!ENGINE_init(engine))
248 {
249 LOG(ERROR) << "Cannot initialize the OpenSSL dynamic engine for PKCS11";
250 throw OrthancException(ErrorCode_InternalError);
251 }
252
253 LOG(WARNING) << "The PKCS11 engine has been successfully initialized";
254 pkcs11Initialized_ = true;
255 } 166 }
256 #endif 167 #endif
257 }; 168 };
258 169
259 170
286 197
287 198
288 199
289 static CURLcode CheckCode(CURLcode code) 200 static CURLcode CheckCode(CURLcode code)
290 { 201 {
202 if (code == CURLE_NOT_BUILT_IN)
203 {
204 LOG(ERROR) << "Your libcurl does not contain a required feature, "
205 << "please recompile Orthanc with -DUSE_SYSTEM_CURL=OFF";
206 throw OrthancException(ErrorCode_InternalError);
207 }
208
291 if (code != CURLE_OK) 209 if (code != CURLE_OK)
292 { 210 {
293 LOG(ERROR) << "libCURL error: " + std::string(curl_easy_strerror(code)); 211 LOG(ERROR) << "libCURL error: " + std::string(curl_easy_strerror(code));
294 throw OrthancException(ErrorCode_NetworkProtocol); 212 throw OrthancException(ErrorCode_NetworkProtocol);
295 } 213 }
469 if (pkcs11Enabled_) 387 if (pkcs11Enabled_)
470 { 388 {
471 #if ORTHANC_PKCS11_ENABLED == 1 389 #if ORTHANC_PKCS11_ENABLED == 1
472 if (GlobalParameters::GetInstance().IsPkcs11Initialized()) 390 if (GlobalParameters::GetInstance().IsPkcs11Initialized())
473 { 391 {
474 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLENGINE, "pkcs11")); 392 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLENGINE, Pkcs11::GetEngineIdentifier()));
475 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLKEYTYPE, "ENG")); 393 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLKEYTYPE, "ENG"));
476 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLCERTTYPE, "ENG")); 394 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLCERTTYPE, "ENG"));
477 } 395 }
478 else 396 else
479 { 397 {
480 LOG(ERROR) << "Cannot use PKCS11 for a HTTPS request, because it has not been initialized"; 398 LOG(ERROR) << "Cannot use PKCS#11 for a HTTPS request, because it has not been initialized";
481 throw OrthancException(ErrorCode_BadSequenceOfCalls); 399 throw OrthancException(ErrorCode_BadSequenceOfCalls);
482 } 400 }
483 #else 401 #else
484 LOG(ERROR) << "This version of Orthanc is compiled without support for PKCS11"; 402 LOG(ERROR) << "This version of Orthanc is compiled without support for PKCS#11";
485 throw OrthancException(ErrorCode_InternalError); 403 throw OrthancException(ErrorCode_InternalError);
486 #endif 404 #endif
487 } 405 }
488 else if (!clientCertificateFile_.empty()) 406 else if (!clientCertificateFile_.empty())
489 { 407 {
702 620
703 621
704 void HttpClient::GlobalFinalize() 622 void HttpClient::GlobalFinalize()
705 { 623 {
706 curl_global_cleanup(); 624 curl_global_cleanup();
625
626 #if ORTHANC_PKCS11_ENABLED == 1
627 Pkcs11::Finalize();
628 #endif
707 } 629 }
708 630
709 631
710 void HttpClient::SetDefaultProxy(const std::string& proxy) 632 void HttpClient::SetDefaultProxy(const std::string& proxy)
711 { 633 {
771 #if ORTHANC_PKCS11_ENABLED == 1 693 #if ORTHANC_PKCS11_ENABLED == 1
772 LOG(INFO) << "Initializing PKCS#11 using " << module 694 LOG(INFO) << "Initializing PKCS#11 using " << module
773 << (pin.empty() ? " (no PIN provided)" : " (PIN is provided)"); 695 << (pin.empty() ? " (no PIN provided)" : " (PIN is provided)");
774 GlobalParameters::GetInstance().InitializePkcs11(module, pin, verbose); 696 GlobalParameters::GetInstance().InitializePkcs11(module, pin, verbose);
775 #else 697 #else
776 LOG(ERROR) << "This version of Orthanc is compiled without support for PKCS11"; 698 LOG(ERROR) << "This version of Orthanc is compiled without support for PKCS#11";
777 throw OrthancException(ErrorCode_InternalError); 699 throw OrthancException(ErrorCode_InternalError);
778 #endif 700 #endif
779 } 701 }
780 } 702 }