Mercurial > hg > orthanc
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 } |