Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

context.ipp 32KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204
  1. //
  2. // ssl/impl/context.ipp
  3. // ~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
  6. // Copyright (c) 2005-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  7. //
  8. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  9. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. #ifndef ASIO_SSL_IMPL_CONTEXT_IPP
  12. #define ASIO_SSL_IMPL_CONTEXT_IPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  16. #include "asio/detail/config.hpp"
  17. #include <cstring>
  18. #include "asio/detail/throw_error.hpp"
  19. #include "asio/error.hpp"
  20. #include "asio/ssl/context.hpp"
  21. #include "asio/ssl/error.hpp"
  22. #include "asio/detail/push_options.hpp"
  23. namespace asio {
  24. namespace ssl {
  25. struct context::bio_cleanup
  26. {
  27. BIO* p;
  28. ~bio_cleanup() { if (p) ::BIO_free(p); }
  29. };
  30. struct context::x509_cleanup
  31. {
  32. X509* p;
  33. ~x509_cleanup() { if (p) ::X509_free(p); }
  34. };
  35. struct context::evp_pkey_cleanup
  36. {
  37. EVP_PKEY* p;
  38. ~evp_pkey_cleanup() { if (p) ::EVP_PKEY_free(p); }
  39. };
  40. struct context::rsa_cleanup
  41. {
  42. RSA* p;
  43. ~rsa_cleanup() { if (p) ::RSA_free(p); }
  44. };
  45. struct context::dh_cleanup
  46. {
  47. DH* p;
  48. ~dh_cleanup() { if (p) ::DH_free(p); }
  49. };
  50. context::context(context::method m)
  51. : handle_(0)
  52. {
  53. ::ERR_clear_error();
  54. switch (m)
  55. {
  56. // SSL v2.
  57. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) || defined(OPENSSL_NO_SSL2)
  58. case context::sslv2:
  59. case context::sslv2_client:
  60. case context::sslv2_server:
  61. asio::detail::throw_error(
  62. asio::error::invalid_argument, "context");
  63. break;
  64. #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L) || defined(OPENSSL_NO_SSL2)
  65. case context::sslv2:
  66. handle_ = ::SSL_CTX_new(::SSLv2_method());
  67. break;
  68. case context::sslv2_client:
  69. handle_ = ::SSL_CTX_new(::SSLv2_client_method());
  70. break;
  71. case context::sslv2_server:
  72. handle_ = ::SSL_CTX_new(::SSLv2_server_method());
  73. break;
  74. #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L) || defined(OPENSSL_NO_SSL2)
  75. // SSL v3.
  76. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
  77. case context::sslv3:
  78. handle_ = ::SSL_CTX_new(::TLS_method());
  79. if (handle_)
  80. {
  81. SSL_CTX_set_min_proto_version(handle_, SSL3_VERSION);
  82. SSL_CTX_set_max_proto_version(handle_, SSL3_VERSION);
  83. }
  84. break;
  85. case context::sslv3_client:
  86. handle_ = ::SSL_CTX_new(::TLS_client_method());
  87. if (handle_)
  88. {
  89. SSL_CTX_set_min_proto_version(handle_, SSL3_VERSION);
  90. SSL_CTX_set_max_proto_version(handle_, SSL3_VERSION);
  91. }
  92. break;
  93. case context::sslv3_server:
  94. handle_ = ::SSL_CTX_new(::TLS_server_method());
  95. if (handle_)
  96. {
  97. SSL_CTX_set_min_proto_version(handle_, SSL3_VERSION);
  98. SSL_CTX_set_max_proto_version(handle_, SSL3_VERSION);
  99. }
  100. break;
  101. #elif defined(OPENSSL_NO_SSL3)
  102. case context::sslv3:
  103. case context::sslv3_client:
  104. case context::sslv3_server:
  105. asio::detail::throw_error(
  106. asio::error::invalid_argument, "context");
  107. break;
  108. #else // defined(OPENSSL_NO_SSL3)
  109. case context::sslv3:
  110. handle_ = ::SSL_CTX_new(::SSLv3_method());
  111. break;
  112. case context::sslv3_client:
  113. handle_ = ::SSL_CTX_new(::SSLv3_client_method());
  114. break;
  115. case context::sslv3_server:
  116. handle_ = ::SSL_CTX_new(::SSLv3_server_method());
  117. break;
  118. #endif // defined(OPENSSL_NO_SSL3)
  119. // TLS v1.0.
  120. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
  121. case context::tlsv1:
  122. handle_ = ::SSL_CTX_new(::TLS_method());
  123. if (handle_)
  124. {
  125. SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION);
  126. SSL_CTX_set_max_proto_version(handle_, TLS1_VERSION);
  127. }
  128. break;
  129. case context::tlsv1_client:
  130. handle_ = ::SSL_CTX_new(::TLS_client_method());
  131. if (handle_)
  132. {
  133. SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION);
  134. SSL_CTX_set_max_proto_version(handle_, TLS1_VERSION);
  135. }
  136. break;
  137. case context::tlsv1_server:
  138. handle_ = ::SSL_CTX_new(::TLS_server_method());
  139. if (handle_)
  140. {
  141. SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION);
  142. SSL_CTX_set_max_proto_version(handle_, TLS1_VERSION);
  143. }
  144. break;
  145. #elif defined(SSL_TXT_TLSV1)
  146. case context::tlsv1:
  147. handle_ = ::SSL_CTX_new(::TLSv1_method());
  148. break;
  149. case context::tlsv1_client:
  150. handle_ = ::SSL_CTX_new(::TLSv1_client_method());
  151. break;
  152. case context::tlsv1_server:
  153. handle_ = ::SSL_CTX_new(::TLSv1_server_method());
  154. break;
  155. #else // defined(SSL_TXT_TLSV1)
  156. case context::tlsv1:
  157. case context::tlsv1_client:
  158. case context::tlsv1_server:
  159. asio::detail::throw_error(
  160. asio::error::invalid_argument, "context");
  161. break;
  162. #endif // defined(SSL_TXT_TLSV1)
  163. // TLS v1.1.
  164. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
  165. case context::tlsv11:
  166. handle_ = ::SSL_CTX_new(::TLS_method());
  167. if (handle_)
  168. {
  169. SSL_CTX_set_min_proto_version(handle_, TLS1_1_VERSION);
  170. SSL_CTX_set_max_proto_version(handle_, TLS1_1_VERSION);
  171. }
  172. break;
  173. case context::tlsv11_client:
  174. handle_ = ::SSL_CTX_new(::TLS_client_method());
  175. if (handle_)
  176. {
  177. SSL_CTX_set_min_proto_version(handle_, TLS1_1_VERSION);
  178. SSL_CTX_set_max_proto_version(handle_, TLS1_1_VERSION);
  179. }
  180. break;
  181. case context::tlsv11_server:
  182. handle_ = ::SSL_CTX_new(::TLS_server_method());
  183. if (handle_)
  184. {
  185. SSL_CTX_set_min_proto_version(handle_, TLS1_1_VERSION);
  186. SSL_CTX_set_max_proto_version(handle_, TLS1_1_VERSION);
  187. }
  188. break;
  189. #elif defined(SSL_TXT_TLSV1_1)
  190. case context::tlsv11:
  191. handle_ = ::SSL_CTX_new(::TLSv1_1_method());
  192. break;
  193. case context::tlsv11_client:
  194. handle_ = ::SSL_CTX_new(::TLSv1_1_client_method());
  195. break;
  196. case context::tlsv11_server:
  197. handle_ = ::SSL_CTX_new(::TLSv1_1_server_method());
  198. break;
  199. #else // defined(SSL_TXT_TLSV1_1)
  200. case context::tlsv11:
  201. case context::tlsv11_client:
  202. case context::tlsv11_server:
  203. asio::detail::throw_error(
  204. asio::error::invalid_argument, "context");
  205. break;
  206. #endif // defined(SSL_TXT_TLSV1_1)
  207. // TLS v1.2.
  208. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
  209. case context::tlsv12:
  210. handle_ = ::SSL_CTX_new(::TLS_method());
  211. if (handle_)
  212. {
  213. SSL_CTX_set_min_proto_version(handle_, TLS1_2_VERSION);
  214. SSL_CTX_set_max_proto_version(handle_, TLS1_2_VERSION);
  215. }
  216. break;
  217. case context::tlsv12_client:
  218. handle_ = ::SSL_CTX_new(::TLS_client_method());
  219. if (handle_)
  220. {
  221. SSL_CTX_set_min_proto_version(handle_, TLS1_2_VERSION);
  222. SSL_CTX_set_max_proto_version(handle_, TLS1_2_VERSION);
  223. }
  224. break;
  225. case context::tlsv12_server:
  226. handle_ = ::SSL_CTX_new(::TLS_server_method());
  227. if (handle_)
  228. {
  229. SSL_CTX_set_min_proto_version(handle_, TLS1_2_VERSION);
  230. SSL_CTX_set_max_proto_version(handle_, TLS1_2_VERSION);
  231. }
  232. break;
  233. #elif defined(SSL_TXT_TLSV1_2)
  234. case context::tlsv12:
  235. handle_ = ::SSL_CTX_new(::TLSv1_2_method());
  236. break;
  237. case context::tlsv12_client:
  238. handle_ = ::SSL_CTX_new(::TLSv1_2_client_method());
  239. break;
  240. case context::tlsv12_server:
  241. handle_ = ::SSL_CTX_new(::TLSv1_2_server_method());
  242. break;
  243. #else // defined(SSL_TXT_TLSV1_2)
  244. case context::tlsv12:
  245. case context::tlsv12_client:
  246. case context::tlsv12_server:
  247. asio::detail::throw_error(
  248. asio::error::invalid_argument, "context");
  249. break;
  250. #endif // defined(SSL_TXT_TLSV1_2)
  251. // TLS v1.3.
  252. #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) \
  253. && !defined(LIBRESSL_VERSION_NUMBER)
  254. case context::tlsv13:
  255. handle_ = ::SSL_CTX_new(::TLS_method());
  256. if (handle_)
  257. {
  258. SSL_CTX_set_min_proto_version(handle_, TLS1_3_VERSION);
  259. SSL_CTX_set_max_proto_version(handle_, TLS1_3_VERSION);
  260. }
  261. break;
  262. case context::tlsv13_client:
  263. handle_ = ::SSL_CTX_new(::TLS_client_method());
  264. if (handle_)
  265. {
  266. SSL_CTX_set_min_proto_version(handle_, TLS1_3_VERSION);
  267. SSL_CTX_set_max_proto_version(handle_, TLS1_3_VERSION);
  268. }
  269. break;
  270. case context::tlsv13_server:
  271. handle_ = ::SSL_CTX_new(::TLS_server_method());
  272. if (handle_)
  273. {
  274. SSL_CTX_set_min_proto_version(handle_, TLS1_3_VERSION);
  275. SSL_CTX_set_max_proto_version(handle_, TLS1_3_VERSION);
  276. }
  277. break;
  278. #else // (OPENSSL_VERSION_NUMBER >= 0x10101000L)
  279. // && !defined(LIBRESSL_VERSION_NUMBER)
  280. case context::tlsv13:
  281. case context::tlsv13_client:
  282. case context::tlsv13_server:
  283. asio::detail::throw_error(
  284. asio::error::invalid_argument, "context");
  285. break;
  286. #endif // (OPENSSL_VERSION_NUMBER >= 0x10101000L)
  287. // && !defined(LIBRESSL_VERSION_NUMBER)
  288. // Any supported SSL/TLS version.
  289. case context::sslv23:
  290. handle_ = ::SSL_CTX_new(::SSLv23_method());
  291. break;
  292. case context::sslv23_client:
  293. handle_ = ::SSL_CTX_new(::SSLv23_client_method());
  294. break;
  295. case context::sslv23_server:
  296. handle_ = ::SSL_CTX_new(::SSLv23_server_method());
  297. break;
  298. // Any supported TLS version.
  299. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
  300. case context::tls:
  301. handle_ = ::SSL_CTX_new(::TLS_method());
  302. if (handle_)
  303. SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION);
  304. break;
  305. case context::tls_client:
  306. handle_ = ::SSL_CTX_new(::TLS_client_method());
  307. if (handle_)
  308. SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION);
  309. break;
  310. case context::tls_server:
  311. handle_ = ::SSL_CTX_new(::TLS_server_method());
  312. if (handle_)
  313. SSL_CTX_set_min_proto_version(handle_, TLS1_VERSION);
  314. break;
  315. #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
  316. case context::tls:
  317. handle_ = ::SSL_CTX_new(::SSLv23_method());
  318. if (handle_)
  319. SSL_CTX_set_options(handle_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
  320. break;
  321. case context::tls_client:
  322. handle_ = ::SSL_CTX_new(::SSLv23_client_method());
  323. if (handle_)
  324. SSL_CTX_set_options(handle_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
  325. break;
  326. case context::tls_server:
  327. handle_ = ::SSL_CTX_new(::SSLv23_server_method());
  328. if (handle_)
  329. SSL_CTX_set_options(handle_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
  330. break;
  331. #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
  332. default:
  333. handle_ = ::SSL_CTX_new(0);
  334. break;
  335. }
  336. if (handle_ == 0)
  337. {
  338. asio::error_code ec(
  339. static_cast<int>(::ERR_get_error()),
  340. asio::error::get_ssl_category());
  341. asio::detail::throw_error(ec, "context");
  342. }
  343. set_options(no_compression);
  344. }
  345. #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  346. context::context(context&& other)
  347. {
  348. handle_ = other.handle_;
  349. other.handle_ = 0;
  350. }
  351. context& context::operator=(context&& other)
  352. {
  353. context tmp(ASIO_MOVE_CAST(context)(*this));
  354. handle_ = other.handle_;
  355. other.handle_ = 0;
  356. return *this;
  357. }
  358. #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  359. context::~context()
  360. {
  361. if (handle_)
  362. {
  363. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
  364. void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
  365. #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
  366. void* cb_userdata = handle_->default_passwd_callback_userdata;
  367. #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
  368. if (cb_userdata)
  369. {
  370. detail::password_callback_base* callback =
  371. static_cast<detail::password_callback_base*>(
  372. cb_userdata);
  373. delete callback;
  374. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
  375. ::SSL_CTX_set_default_passwd_cb_userdata(handle_, 0);
  376. #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
  377. handle_->default_passwd_callback_userdata = 0;
  378. #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
  379. }
  380. if (SSL_CTX_get_app_data(handle_))
  381. {
  382. detail::verify_callback_base* callback =
  383. static_cast<detail::verify_callback_base*>(
  384. SSL_CTX_get_app_data(handle_));
  385. delete callback;
  386. SSL_CTX_set_app_data(handle_, 0);
  387. }
  388. ::SSL_CTX_free(handle_);
  389. }
  390. }
  391. context::native_handle_type context::native_handle()
  392. {
  393. return handle_;
  394. }
  395. void context::clear_options(context::options o)
  396. {
  397. asio::error_code ec;
  398. clear_options(o, ec);
  399. asio::detail::throw_error(ec, "clear_options");
  400. }
  401. ASIO_SYNC_OP_VOID context::clear_options(
  402. context::options o, asio::error_code& ec)
  403. {
  404. #if (OPENSSL_VERSION_NUMBER >= 0x009080DFL) \
  405. && (OPENSSL_VERSION_NUMBER != 0x00909000L)
  406. # if !defined(SSL_OP_NO_COMPRESSION)
  407. if ((o & context::no_compression) != 0)
  408. {
  409. # if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
  410. handle_->comp_methods = SSL_COMP_get_compression_methods();
  411. # endif // (OPENSSL_VERSION_NUMBER >= 0x00908000L)
  412. o ^= context::no_compression;
  413. }
  414. # endif // !defined(SSL_OP_NO_COMPRESSION)
  415. ::SSL_CTX_clear_options(handle_, o);
  416. ec = asio::error_code();
  417. #else // (OPENSSL_VERSION_NUMBER >= 0x009080DFL)
  418. // && (OPENSSL_VERSION_NUMBER != 0x00909000L)
  419. (void)o;
  420. ec = asio::error::operation_not_supported;
  421. #endif // (OPENSSL_VERSION_NUMBER >= 0x009080DFL)
  422. // && (OPENSSL_VERSION_NUMBER != 0x00909000L)
  423. ASIO_SYNC_OP_VOID_RETURN(ec);
  424. }
  425. void context::set_options(context::options o)
  426. {
  427. asio::error_code ec;
  428. set_options(o, ec);
  429. asio::detail::throw_error(ec, "set_options");
  430. }
  431. ASIO_SYNC_OP_VOID context::set_options(
  432. context::options o, asio::error_code& ec)
  433. {
  434. #if !defined(SSL_OP_NO_COMPRESSION)
  435. if ((o & context::no_compression) != 0)
  436. {
  437. #if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
  438. handle_->comp_methods =
  439. asio::ssl::detail::openssl_init<>::get_null_compression_methods();
  440. #endif // (OPENSSL_VERSION_NUMBER >= 0x00908000L)
  441. o ^= context::no_compression;
  442. }
  443. #endif // !defined(SSL_OP_NO_COMPRESSION)
  444. ::SSL_CTX_set_options(handle_, o);
  445. ec = asio::error_code();
  446. ASIO_SYNC_OP_VOID_RETURN(ec);
  447. }
  448. void context::set_verify_mode(verify_mode v)
  449. {
  450. asio::error_code ec;
  451. set_verify_mode(v, ec);
  452. asio::detail::throw_error(ec, "set_verify_mode");
  453. }
  454. ASIO_SYNC_OP_VOID context::set_verify_mode(
  455. verify_mode v, asio::error_code& ec)
  456. {
  457. ::SSL_CTX_set_verify(handle_, v, ::SSL_CTX_get_verify_callback(handle_));
  458. ec = asio::error_code();
  459. ASIO_SYNC_OP_VOID_RETURN(ec);
  460. }
  461. void context::set_verify_depth(int depth)
  462. {
  463. asio::error_code ec;
  464. set_verify_depth(depth, ec);
  465. asio::detail::throw_error(ec, "set_verify_depth");
  466. }
  467. ASIO_SYNC_OP_VOID context::set_verify_depth(
  468. int depth, asio::error_code& ec)
  469. {
  470. ::SSL_CTX_set_verify_depth(handle_, depth);
  471. ec = asio::error_code();
  472. ASIO_SYNC_OP_VOID_RETURN(ec);
  473. }
  474. void context::load_verify_file(const std::string& filename)
  475. {
  476. asio::error_code ec;
  477. load_verify_file(filename, ec);
  478. asio::detail::throw_error(ec, "load_verify_file");
  479. }
  480. ASIO_SYNC_OP_VOID context::load_verify_file(
  481. const std::string& filename, asio::error_code& ec)
  482. {
  483. ::ERR_clear_error();
  484. if (::SSL_CTX_load_verify_locations(handle_, filename.c_str(), 0) != 1)
  485. {
  486. ec = asio::error_code(
  487. static_cast<int>(::ERR_get_error()),
  488. asio::error::get_ssl_category());
  489. ASIO_SYNC_OP_VOID_RETURN(ec);
  490. }
  491. ec = asio::error_code();
  492. ASIO_SYNC_OP_VOID_RETURN(ec);
  493. }
  494. void context::add_certificate_authority(const const_buffer& ca)
  495. {
  496. asio::error_code ec;
  497. add_certificate_authority(ca, ec);
  498. asio::detail::throw_error(ec, "add_certificate_authority");
  499. }
  500. ASIO_SYNC_OP_VOID context::add_certificate_authority(
  501. const const_buffer& ca, asio::error_code& ec)
  502. {
  503. ::ERR_clear_error();
  504. bio_cleanup bio = { make_buffer_bio(ca) };
  505. if (bio.p)
  506. {
  507. if (X509_STORE* store = ::SSL_CTX_get_cert_store(handle_))
  508. {
  509. for (;;)
  510. {
  511. x509_cleanup cert = { ::PEM_read_bio_X509(bio.p, 0, 0, 0) };
  512. if (!cert.p)
  513. break;
  514. if (::X509_STORE_add_cert(store, cert.p) != 1)
  515. {
  516. ec = asio::error_code(
  517. static_cast<int>(::ERR_get_error()),
  518. asio::error::get_ssl_category());
  519. ASIO_SYNC_OP_VOID_RETURN(ec);
  520. }
  521. }
  522. }
  523. }
  524. ec = asio::error_code();
  525. ASIO_SYNC_OP_VOID_RETURN(ec);
  526. }
  527. void context::set_default_verify_paths()
  528. {
  529. asio::error_code ec;
  530. set_default_verify_paths(ec);
  531. asio::detail::throw_error(ec, "set_default_verify_paths");
  532. }
  533. ASIO_SYNC_OP_VOID context::set_default_verify_paths(
  534. asio::error_code& ec)
  535. {
  536. ::ERR_clear_error();
  537. if (::SSL_CTX_set_default_verify_paths(handle_) != 1)
  538. {
  539. ec = asio::error_code(
  540. static_cast<int>(::ERR_get_error()),
  541. asio::error::get_ssl_category());
  542. ASIO_SYNC_OP_VOID_RETURN(ec);
  543. }
  544. ec = asio::error_code();
  545. ASIO_SYNC_OP_VOID_RETURN(ec);
  546. }
  547. void context::add_verify_path(const std::string& path)
  548. {
  549. asio::error_code ec;
  550. add_verify_path(path, ec);
  551. asio::detail::throw_error(ec, "add_verify_path");
  552. }
  553. ASIO_SYNC_OP_VOID context::add_verify_path(
  554. const std::string& path, asio::error_code& ec)
  555. {
  556. ::ERR_clear_error();
  557. if (::SSL_CTX_load_verify_locations(handle_, 0, path.c_str()) != 1)
  558. {
  559. ec = asio::error_code(
  560. static_cast<int>(::ERR_get_error()),
  561. asio::error::get_ssl_category());
  562. ASIO_SYNC_OP_VOID_RETURN(ec);
  563. }
  564. ec = asio::error_code();
  565. ASIO_SYNC_OP_VOID_RETURN(ec);
  566. }
  567. void context::use_certificate(
  568. const const_buffer& certificate, file_format format)
  569. {
  570. asio::error_code ec;
  571. use_certificate(certificate, format, ec);
  572. asio::detail::throw_error(ec, "use_certificate");
  573. }
  574. ASIO_SYNC_OP_VOID context::use_certificate(
  575. const const_buffer& certificate, file_format format,
  576. asio::error_code& ec)
  577. {
  578. ::ERR_clear_error();
  579. if (format == context_base::asn1)
  580. {
  581. if (::SSL_CTX_use_certificate_ASN1(handle_,
  582. static_cast<int>(certificate.size()),
  583. static_cast<const unsigned char*>(certificate.data())) == 1)
  584. {
  585. ec = asio::error_code();
  586. ASIO_SYNC_OP_VOID_RETURN(ec);
  587. }
  588. }
  589. else if (format == context_base::pem)
  590. {
  591. bio_cleanup bio = { make_buffer_bio(certificate) };
  592. if (bio.p)
  593. {
  594. x509_cleanup cert = { ::PEM_read_bio_X509(bio.p, 0, 0, 0) };
  595. if (cert.p)
  596. {
  597. if (::SSL_CTX_use_certificate(handle_, cert.p) == 1)
  598. {
  599. ec = asio::error_code();
  600. ASIO_SYNC_OP_VOID_RETURN(ec);
  601. }
  602. }
  603. }
  604. }
  605. else
  606. {
  607. ec = asio::error::invalid_argument;
  608. ASIO_SYNC_OP_VOID_RETURN(ec);
  609. }
  610. ec = asio::error_code(
  611. static_cast<int>(::ERR_get_error()),
  612. asio::error::get_ssl_category());
  613. ASIO_SYNC_OP_VOID_RETURN(ec);
  614. }
  615. void context::use_certificate_file(
  616. const std::string& filename, file_format format)
  617. {
  618. asio::error_code ec;
  619. use_certificate_file(filename, format, ec);
  620. asio::detail::throw_error(ec, "use_certificate_file");
  621. }
  622. ASIO_SYNC_OP_VOID context::use_certificate_file(
  623. const std::string& filename, file_format format,
  624. asio::error_code& ec)
  625. {
  626. int file_type;
  627. switch (format)
  628. {
  629. case context_base::asn1:
  630. file_type = SSL_FILETYPE_ASN1;
  631. break;
  632. case context_base::pem:
  633. file_type = SSL_FILETYPE_PEM;
  634. break;
  635. default:
  636. {
  637. ec = asio::error::invalid_argument;
  638. ASIO_SYNC_OP_VOID_RETURN(ec);
  639. }
  640. }
  641. ::ERR_clear_error();
  642. if (::SSL_CTX_use_certificate_file(handle_, filename.c_str(), file_type) != 1)
  643. {
  644. ec = asio::error_code(
  645. static_cast<int>(::ERR_get_error()),
  646. asio::error::get_ssl_category());
  647. ASIO_SYNC_OP_VOID_RETURN(ec);
  648. }
  649. ec = asio::error_code();
  650. ASIO_SYNC_OP_VOID_RETURN(ec);
  651. }
  652. void context::use_certificate_chain(const const_buffer& chain)
  653. {
  654. asio::error_code ec;
  655. use_certificate_chain(chain, ec);
  656. asio::detail::throw_error(ec, "use_certificate_chain");
  657. }
  658. ASIO_SYNC_OP_VOID context::use_certificate_chain(
  659. const const_buffer& chain, asio::error_code& ec)
  660. {
  661. ::ERR_clear_error();
  662. bio_cleanup bio = { make_buffer_bio(chain) };
  663. if (bio.p)
  664. {
  665. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
  666. pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
  667. void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
  668. #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
  669. pem_password_cb* callback = handle_->default_passwd_callback;
  670. void* cb_userdata = handle_->default_passwd_callback_userdata;
  671. #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
  672. x509_cleanup cert = {
  673. ::PEM_read_bio_X509_AUX(bio.p, 0,
  674. callback,
  675. cb_userdata) };
  676. if (!cert.p)
  677. {
  678. ec = asio::error_code(ERR_R_PEM_LIB,
  679. asio::error::get_ssl_category());
  680. ASIO_SYNC_OP_VOID_RETURN(ec);
  681. }
  682. int result = ::SSL_CTX_use_certificate(handle_, cert.p);
  683. if (result == 0 || ::ERR_peek_error() != 0)
  684. {
  685. ec = asio::error_code(
  686. static_cast<int>(::ERR_get_error()),
  687. asio::error::get_ssl_category());
  688. ASIO_SYNC_OP_VOID_RETURN(ec);
  689. }
  690. #if (OPENSSL_VERSION_NUMBER >= 0x10002000L) && !defined(LIBRESSL_VERSION_NUMBER)
  691. ::SSL_CTX_clear_chain_certs(handle_);
  692. #else
  693. if (handle_->extra_certs)
  694. {
  695. ::sk_X509_pop_free(handle_->extra_certs, X509_free);
  696. handle_->extra_certs = 0;
  697. }
  698. #endif // (OPENSSL_VERSION_NUMBER >= 0x10002000L)
  699. while (X509* cacert = ::PEM_read_bio_X509(bio.p, 0,
  700. callback,
  701. cb_userdata))
  702. {
  703. if (!::SSL_CTX_add_extra_chain_cert(handle_, cacert))
  704. {
  705. ec = asio::error_code(
  706. static_cast<int>(::ERR_get_error()),
  707. asio::error::get_ssl_category());
  708. ASIO_SYNC_OP_VOID_RETURN(ec);
  709. }
  710. }
  711. result = ::ERR_peek_last_error();
  712. if ((ERR_GET_LIB(result) == ERR_LIB_PEM)
  713. && (ERR_GET_REASON(result) == PEM_R_NO_START_LINE))
  714. {
  715. ::ERR_clear_error();
  716. ec = asio::error_code();
  717. ASIO_SYNC_OP_VOID_RETURN(ec);
  718. }
  719. }
  720. ec = asio::error_code(
  721. static_cast<int>(::ERR_get_error()),
  722. asio::error::get_ssl_category());
  723. ASIO_SYNC_OP_VOID_RETURN(ec);
  724. }
  725. void context::use_certificate_chain_file(const std::string& filename)
  726. {
  727. asio::error_code ec;
  728. use_certificate_chain_file(filename, ec);
  729. asio::detail::throw_error(ec, "use_certificate_chain_file");
  730. }
  731. ASIO_SYNC_OP_VOID context::use_certificate_chain_file(
  732. const std::string& filename, asio::error_code& ec)
  733. {
  734. ::ERR_clear_error();
  735. if (::SSL_CTX_use_certificate_chain_file(handle_, filename.c_str()) != 1)
  736. {
  737. ec = asio::error_code(
  738. static_cast<int>(::ERR_get_error()),
  739. asio::error::get_ssl_category());
  740. ASIO_SYNC_OP_VOID_RETURN(ec);
  741. }
  742. ec = asio::error_code();
  743. ASIO_SYNC_OP_VOID_RETURN(ec);
  744. }
  745. void context::use_private_key(
  746. const const_buffer& private_key, context::file_format format)
  747. {
  748. asio::error_code ec;
  749. use_private_key(private_key, format, ec);
  750. asio::detail::throw_error(ec, "use_private_key");
  751. }
  752. ASIO_SYNC_OP_VOID context::use_private_key(
  753. const const_buffer& private_key, context::file_format format,
  754. asio::error_code& ec)
  755. {
  756. ::ERR_clear_error();
  757. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
  758. pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
  759. void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
  760. #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
  761. pem_password_cb* callback = handle_->default_passwd_callback;
  762. void* cb_userdata = handle_->default_passwd_callback_userdata;
  763. #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
  764. bio_cleanup bio = { make_buffer_bio(private_key) };
  765. if (bio.p)
  766. {
  767. evp_pkey_cleanup evp_private_key = { 0 };
  768. switch (format)
  769. {
  770. case context_base::asn1:
  771. evp_private_key.p = ::d2i_PrivateKey_bio(bio.p, 0);
  772. break;
  773. case context_base::pem:
  774. evp_private_key.p = ::PEM_read_bio_PrivateKey(
  775. bio.p, 0, callback,
  776. cb_userdata);
  777. break;
  778. default:
  779. {
  780. ec = asio::error::invalid_argument;
  781. ASIO_SYNC_OP_VOID_RETURN(ec);
  782. }
  783. }
  784. if (evp_private_key.p)
  785. {
  786. if (::SSL_CTX_use_PrivateKey(handle_, evp_private_key.p) == 1)
  787. {
  788. ec = asio::error_code();
  789. ASIO_SYNC_OP_VOID_RETURN(ec);
  790. }
  791. }
  792. }
  793. ec = asio::error_code(
  794. static_cast<int>(::ERR_get_error()),
  795. asio::error::get_ssl_category());
  796. ASIO_SYNC_OP_VOID_RETURN(ec);
  797. }
  798. void context::use_private_key_file(
  799. const std::string& filename, context::file_format format)
  800. {
  801. asio::error_code ec;
  802. use_private_key_file(filename, format, ec);
  803. asio::detail::throw_error(ec, "use_private_key_file");
  804. }
  805. void context::use_rsa_private_key(
  806. const const_buffer& private_key, context::file_format format)
  807. {
  808. asio::error_code ec;
  809. use_rsa_private_key(private_key, format, ec);
  810. asio::detail::throw_error(ec, "use_rsa_private_key");
  811. }
  812. ASIO_SYNC_OP_VOID context::use_rsa_private_key(
  813. const const_buffer& private_key, context::file_format format,
  814. asio::error_code& ec)
  815. {
  816. ::ERR_clear_error();
  817. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
  818. pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
  819. void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
  820. #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
  821. pem_password_cb* callback = handle_->default_passwd_callback;
  822. void* cb_userdata = handle_->default_passwd_callback_userdata;
  823. #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
  824. bio_cleanup bio = { make_buffer_bio(private_key) };
  825. if (bio.p)
  826. {
  827. rsa_cleanup rsa_private_key = { 0 };
  828. switch (format)
  829. {
  830. case context_base::asn1:
  831. rsa_private_key.p = ::d2i_RSAPrivateKey_bio(bio.p, 0);
  832. break;
  833. case context_base::pem:
  834. rsa_private_key.p = ::PEM_read_bio_RSAPrivateKey(
  835. bio.p, 0, callback,
  836. cb_userdata);
  837. break;
  838. default:
  839. {
  840. ec = asio::error::invalid_argument;
  841. ASIO_SYNC_OP_VOID_RETURN(ec);
  842. }
  843. }
  844. if (rsa_private_key.p)
  845. {
  846. if (::SSL_CTX_use_RSAPrivateKey(handle_, rsa_private_key.p) == 1)
  847. {
  848. ec = asio::error_code();
  849. ASIO_SYNC_OP_VOID_RETURN(ec);
  850. }
  851. }
  852. }
  853. ec = asio::error_code(
  854. static_cast<int>(::ERR_get_error()),
  855. asio::error::get_ssl_category());
  856. ASIO_SYNC_OP_VOID_RETURN(ec);
  857. }
  858. ASIO_SYNC_OP_VOID context::use_private_key_file(
  859. const std::string& filename, context::file_format format,
  860. asio::error_code& ec)
  861. {
  862. int file_type;
  863. switch (format)
  864. {
  865. case context_base::asn1:
  866. file_type = SSL_FILETYPE_ASN1;
  867. break;
  868. case context_base::pem:
  869. file_type = SSL_FILETYPE_PEM;
  870. break;
  871. default:
  872. {
  873. ec = asio::error::invalid_argument;
  874. ASIO_SYNC_OP_VOID_RETURN(ec);
  875. }
  876. }
  877. ::ERR_clear_error();
  878. if (::SSL_CTX_use_PrivateKey_file(handle_, filename.c_str(), file_type) != 1)
  879. {
  880. ec = asio::error_code(
  881. static_cast<int>(::ERR_get_error()),
  882. asio::error::get_ssl_category());
  883. ASIO_SYNC_OP_VOID_RETURN(ec);
  884. }
  885. ec = asio::error_code();
  886. ASIO_SYNC_OP_VOID_RETURN(ec);
  887. }
  888. void context::use_rsa_private_key_file(
  889. const std::string& filename, context::file_format format)
  890. {
  891. asio::error_code ec;
  892. use_rsa_private_key_file(filename, format, ec);
  893. asio::detail::throw_error(ec, "use_rsa_private_key_file");
  894. }
  895. ASIO_SYNC_OP_VOID context::use_rsa_private_key_file(
  896. const std::string& filename, context::file_format format,
  897. asio::error_code& ec)
  898. {
  899. int file_type;
  900. switch (format)
  901. {
  902. case context_base::asn1:
  903. file_type = SSL_FILETYPE_ASN1;
  904. break;
  905. case context_base::pem:
  906. file_type = SSL_FILETYPE_PEM;
  907. break;
  908. default:
  909. {
  910. ec = asio::error::invalid_argument;
  911. ASIO_SYNC_OP_VOID_RETURN(ec);
  912. }
  913. }
  914. ::ERR_clear_error();
  915. if (::SSL_CTX_use_RSAPrivateKey_file(
  916. handle_, filename.c_str(), file_type) != 1)
  917. {
  918. ec = asio::error_code(
  919. static_cast<int>(::ERR_get_error()),
  920. asio::error::get_ssl_category());
  921. ASIO_SYNC_OP_VOID_RETURN(ec);
  922. }
  923. ec = asio::error_code();
  924. ASIO_SYNC_OP_VOID_RETURN(ec);
  925. }
  926. void context::use_tmp_dh(const const_buffer& dh)
  927. {
  928. asio::error_code ec;
  929. use_tmp_dh(dh, ec);
  930. asio::detail::throw_error(ec, "use_tmp_dh");
  931. }
  932. ASIO_SYNC_OP_VOID context::use_tmp_dh(
  933. const const_buffer& dh, asio::error_code& ec)
  934. {
  935. ::ERR_clear_error();
  936. bio_cleanup bio = { make_buffer_bio(dh) };
  937. if (bio.p)
  938. {
  939. return do_use_tmp_dh(bio.p, ec);
  940. }
  941. ec = asio::error_code(
  942. static_cast<int>(::ERR_get_error()),
  943. asio::error::get_ssl_category());
  944. ASIO_SYNC_OP_VOID_RETURN(ec);
  945. }
  946. void context::use_tmp_dh_file(const std::string& filename)
  947. {
  948. asio::error_code ec;
  949. use_tmp_dh_file(filename, ec);
  950. asio::detail::throw_error(ec, "use_tmp_dh_file");
  951. }
  952. ASIO_SYNC_OP_VOID context::use_tmp_dh_file(
  953. const std::string& filename, asio::error_code& ec)
  954. {
  955. ::ERR_clear_error();
  956. bio_cleanup bio = { ::BIO_new_file(filename.c_str(), "r") };
  957. if (bio.p)
  958. {
  959. return do_use_tmp_dh(bio.p, ec);
  960. }
  961. ec = asio::error_code(
  962. static_cast<int>(::ERR_get_error()),
  963. asio::error::get_ssl_category());
  964. ASIO_SYNC_OP_VOID_RETURN(ec);
  965. }
  966. ASIO_SYNC_OP_VOID context::do_use_tmp_dh(
  967. BIO* bio, asio::error_code& ec)
  968. {
  969. ::ERR_clear_error();
  970. dh_cleanup dh = { ::PEM_read_bio_DHparams(bio, 0, 0, 0) };
  971. if (dh.p)
  972. {
  973. if (::SSL_CTX_set_tmp_dh(handle_, dh.p) == 1)
  974. {
  975. ec = asio::error_code();
  976. ASIO_SYNC_OP_VOID_RETURN(ec);
  977. }
  978. }
  979. ec = asio::error_code(
  980. static_cast<int>(::ERR_get_error()),
  981. asio::error::get_ssl_category());
  982. ASIO_SYNC_OP_VOID_RETURN(ec);
  983. }
  984. ASIO_SYNC_OP_VOID context::do_set_verify_callback(
  985. detail::verify_callback_base* callback, asio::error_code& ec)
  986. {
  987. if (SSL_CTX_get_app_data(handle_))
  988. {
  989. delete static_cast<detail::verify_callback_base*>(
  990. SSL_CTX_get_app_data(handle_));
  991. }
  992. SSL_CTX_set_app_data(handle_, callback);
  993. ::SSL_CTX_set_verify(handle_,
  994. ::SSL_CTX_get_verify_mode(handle_),
  995. &context::verify_callback_function);
  996. ec = asio::error_code();
  997. ASIO_SYNC_OP_VOID_RETURN(ec);
  998. }
  999. int context::verify_callback_function(int preverified, X509_STORE_CTX* ctx)
  1000. {
  1001. if (ctx)
  1002. {
  1003. if (SSL* ssl = static_cast<SSL*>(
  1004. ::X509_STORE_CTX_get_ex_data(
  1005. ctx, ::SSL_get_ex_data_X509_STORE_CTX_idx())))
  1006. {
  1007. if (SSL_CTX* handle = ::SSL_get_SSL_CTX(ssl))
  1008. {
  1009. if (SSL_CTX_get_app_data(handle))
  1010. {
  1011. detail::verify_callback_base* callback =
  1012. static_cast<detail::verify_callback_base*>(
  1013. SSL_CTX_get_app_data(handle));
  1014. verify_context verify_ctx(ctx);
  1015. return callback->call(preverified != 0, verify_ctx) ? 1 : 0;
  1016. }
  1017. }
  1018. }
  1019. }
  1020. return 0;
  1021. }
  1022. ASIO_SYNC_OP_VOID context::do_set_password_callback(
  1023. detail::password_callback_base* callback, asio::error_code& ec)
  1024. {
  1025. #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
  1026. void* old_callback = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
  1027. ::SSL_CTX_set_default_passwd_cb_userdata(handle_, callback);
  1028. #else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
  1029. void* old_callback = handle_->default_passwd_callback_userdata;
  1030. handle_->default_passwd_callback_userdata = callback;
  1031. #endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
  1032. if (old_callback)
  1033. delete static_cast<detail::password_callback_base*>(
  1034. old_callback);
  1035. SSL_CTX_set_default_passwd_cb(handle_, &context::password_callback_function);
  1036. ec = asio::error_code();
  1037. ASIO_SYNC_OP_VOID_RETURN(ec);
  1038. }
  1039. int context::password_callback_function(
  1040. char* buf, int size, int purpose, void* data)
  1041. {
  1042. using namespace std; // For strncat and strlen.
  1043. if (data)
  1044. {
  1045. detail::password_callback_base* callback =
  1046. static_cast<detail::password_callback_base*>(data);
  1047. std::string passwd = callback->call(static_cast<std::size_t>(size),
  1048. purpose ? context_base::for_writing : context_base::for_reading);
  1049. #if defined(ASIO_HAS_SECURE_RTL)
  1050. strcpy_s(buf, size, passwd.c_str());
  1051. #else // defined(ASIO_HAS_SECURE_RTL)
  1052. *buf = '\0';
  1053. if (size > 0)
  1054. strncat(buf, passwd.c_str(), size - 1);
  1055. #endif // defined(ASIO_HAS_SECURE_RTL)
  1056. return static_cast<int>(strlen(buf));
  1057. }
  1058. return 0;
  1059. }
  1060. BIO* context::make_buffer_bio(const const_buffer& b)
  1061. {
  1062. return ::BIO_new_mem_buf(
  1063. const_cast<void*>(b.data()),
  1064. static_cast<int>(b.size()));
  1065. }
  1066. } // namespace ssl
  1067. } // namespace asio
  1068. #include "asio/detail/pop_options.hpp"
  1069. #endif // ASIO_SSL_IMPL_CONTEXT_IPP