TDE core libraries
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.

kssl.cc 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. /* This file is part of the KDE project
  2. *
  3. * Copyright (C) 2000-2003 George Staikos <staikos@kde.org>
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Library General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Library General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Library General Public License
  16. * along with this library; see the file COPYING.LIB. If not, write to
  17. * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  18. * Boston, MA 02110-1301, USA.
  19. */
  20. #ifdef HAVE_CONFIG_H
  21. #include <config.h>
  22. #endif
  23. // this hack provided by Malte Starostik to avoid glibc/openssl bug
  24. // on some systems
  25. #ifdef KSSL_HAVE_SSL
  26. #include <unistd.h>
  27. #include <netinet/in.h>
  28. #include <sys/socket.h>
  29. #define crypt _openssl_crypt
  30. #include <openssl/ssl.h>
  31. #include <openssl/x509.h>
  32. #include <openssl/x509v3.h>
  33. #include <openssl/pem.h>
  34. #include <openssl/rand.h>
  35. #undef crypt
  36. #endif
  37. #include "kssl.h"
  38. #include <kdebug.h>
  39. #include <kstandarddirs.h>
  40. #include <ksock.h>
  41. #include <ksockaddr.h>
  42. #include <kopenssl.h>
  43. #include <ksslx509v3.h>
  44. #include <ksslpkcs12.h>
  45. #include <ksslsession.h>
  46. #include <tdelocale.h>
  47. #include <ksocks.h>
  48. class KSSLPrivate {
  49. public:
  50. KSSLPrivate() {
  51. lastInitTLS = false;
  52. kossl = KOpenSSLProxy::self();
  53. session = 0L;
  54. }
  55. ~KSSLPrivate() {
  56. delete session;
  57. session = 0L;
  58. }
  59. bool lastInitTLS;
  60. KSSLCertificate::KSSLValidation m_cert_vfy_res;
  61. TQString proxyPeer;
  62. #ifdef KSSL_HAVE_SSL
  63. SSL *m_ssl;
  64. SSL_CTX *m_ctx;
  65. SSL_METHOD *m_meth;
  66. #endif
  67. KSSLSession *session;
  68. KOSSL *kossl;
  69. };
  70. KSSL::KSSL(bool init) {
  71. d = new KSSLPrivate;
  72. m_bInit = false;
  73. m_bAutoReconfig = true;
  74. m_cfg = new KSSLSettings();
  75. #ifdef KSSL_HAVE_SSL
  76. d->m_ssl = 0L;
  77. #endif
  78. if (init)
  79. initialize();
  80. }
  81. KSSL::~KSSL() {
  82. close();
  83. delete m_cfg;
  84. delete d;
  85. }
  86. int KSSL::seedWithEGD() {
  87. int rc = 0;
  88. #ifdef KSSL_HAVE_SSL
  89. if (m_cfg->useEGD() && !m_cfg->getEGDPath().isEmpty()) {
  90. rc = d->kossl->RAND_egd(m_cfg->getEGDPath().latin1());
  91. if (rc < 0)
  92. kdDebug(7029) << "KSSL: Error seeding PRNG with the EGD." << endl;
  93. else kdDebug(7029) << "KSSL: PRNG was seeded with " << rc
  94. << " bytes from the EGD." << endl;
  95. } else if (m_cfg->useEFile() && !m_cfg->getEGDPath().isEmpty()) {
  96. rc = d->kossl->RAND_load_file(m_cfg->getEGDPath().latin1(), -1);
  97. if (rc < 0)
  98. kdDebug(7029) << "KSSL: Error seeding PRNG with the entropy file." << endl;
  99. else kdDebug(7029) << "KSSL: PRNG was seeded with " << rc
  100. << " bytes from the entropy file." << endl;
  101. }
  102. #endif
  103. return rc;
  104. }
  105. bool KSSL::TLSInit() {
  106. #ifdef KSSL_HAVE_SSL
  107. // kdDebug(7029) << "KSSL TLS initialize" << endl;
  108. if (m_bInit)
  109. return false;
  110. if (m_bAutoReconfig)
  111. m_cfg->load();
  112. if (!m_cfg->tlsv1())
  113. return false;
  114. seedWithEGD();
  115. d->m_meth = d->kossl->TLS_client_method();
  116. d->lastInitTLS = true;
  117. m_pi.reset();
  118. d->m_ctx = d->kossl->SSL_CTX_new(d->m_meth);
  119. if (d->m_ctx == 0L) {
  120. return false;
  121. }
  122. // set cipher list
  123. TQString clist = m_cfg->getCipherList();
  124. //kdDebug(7029) << "Cipher list: " << clist << endl;
  125. if (!clist.isEmpty())
  126. d->kossl->SSL_CTX_set_cipher_list(d->m_ctx, const_cast<char *>(clist.ascii()));
  127. m_bInit = true;
  128. return true;
  129. #else
  130. return false;
  131. #endif
  132. }
  133. bool KSSL::initialize() {
  134. #ifdef KSSL_HAVE_SSL
  135. kdDebug(7029) << "KSSL initialize" << endl;
  136. if (m_bInit)
  137. return false;
  138. if (m_bAutoReconfig)
  139. m_cfg->load();
  140. seedWithEGD();
  141. // FIXME: we should be able to force SSL off entirely.
  142. d->lastInitTLS = false;
  143. m_pi.reset();
  144. if (m_cfg->tlsv1() || (m_cfg->sslv3() && m_cfg->sslv2())) {
  145. d->m_meth = d->kossl->TLS_client_method();
  146. }
  147. else if (m_cfg->sslv3()) {
  148. d->m_meth = d->kossl->SSLv3_client_method();
  149. }
  150. else if (m_cfg->sslv2()) {
  151. d->m_meth = d->kossl->SSLv2_client_method();
  152. }
  153. /*
  154. if (m_cfg->sslv2() && m_cfg->sslv3()) kdDebug(7029) << "Double method" << endl;
  155. else if (m_cfg->sslv2()) kdDebug(7029) << "SSL2 method" << endl;
  156. else if (m_cfg->sslv3()) kdDebug(7029) << "SSL3 method" << endl;
  157. */
  158. d->m_ctx = d->kossl->SSL_CTX_new(d->m_meth);
  159. if (d->m_ctx == 0L) {
  160. return false;
  161. }
  162. // set cipher list
  163. TQString clist = m_cfg->getCipherList();
  164. kdDebug(7029) << "Cipher list: " << clist << endl;
  165. if (!clist.isEmpty())
  166. d->kossl->SSL_CTX_set_cipher_list(d->m_ctx, const_cast<char *>(clist.ascii()));
  167. m_bInit = true;
  168. return true;
  169. #else
  170. return false;
  171. #endif
  172. }
  173. bool KSSL::takeSession(KSSLSession *session) {
  174. #ifdef KSSL_HAVE_SSL
  175. if (!session) {
  176. delete d->session;
  177. d->session = 0L;
  178. return true;
  179. }
  180. // Take session reference
  181. d->session = new KSSLSession;
  182. d->session->_session = session->_session;
  183. session->_session = 0L;
  184. return true;
  185. #else
  186. return false;
  187. #endif
  188. }
  189. void KSSL::close() {
  190. #ifdef KSSL_HAVE_SSL
  191. //kdDebug(7029) << "KSSL close" << endl;
  192. if (!m_bInit)
  193. return;
  194. delete d->session;
  195. d->session = 0L;
  196. if (d->m_ssl) {
  197. d->kossl->SSL_shutdown(d->m_ssl);
  198. d->kossl->SSL_free(d->m_ssl);
  199. d->m_ssl = 0L;
  200. }
  201. d->kossl->SSL_CTX_free(d->m_ctx);
  202. if (m_cfg->useEFile() && !m_cfg->getEGDPath().isEmpty()) {
  203. d->kossl->RAND_write_file(m_cfg->getEGDPath().latin1());
  204. }
  205. m_bInit = false;
  206. #endif
  207. }
  208. bool KSSL::reInitialize() {
  209. close();
  210. return initialize();
  211. }
  212. // get the callback file - it's hidden away in here
  213. //#include "ksslcallback.c"
  214. bool KSSL::setVerificationLogic() {
  215. #if 0
  216. #ifdef KSSL_HAVE_SSL
  217. // SSL_set_verify_result(d->m_ssl, X509_V_OK);
  218. // SSL_CTX_set_verify(d->m_ctx, SSL_VERIFY_PEER, X509Callback);
  219. #endif
  220. #endif
  221. return true;
  222. }
  223. int KSSL::accept(int sock) {
  224. #ifdef KSSL_HAVE_SSL
  225. // kdDebug(7029) << "KSSL accept" << endl;
  226. int rc;
  227. if (!m_bInit)
  228. return -1;
  229. d->m_ssl = d->kossl->SSL_new(d->m_ctx);
  230. if (!d->m_ssl)
  231. return -1;
  232. if (d->session) {
  233. #if OPENSSL_VERSION_NUMBER < 0x10100000L
  234. if (static_cast<SSL_SESSION*>(d->session->_session)->sess_cert == 0)
  235. {
  236. kdDebug(7029) << "Can't reuse session, no certificate." << endl;
  237. delete d->session;
  238. d->session = 0;
  239. }
  240. else
  241. #endif
  242. if (1 == d->kossl->SSL_set_session(d->m_ssl,
  243. static_cast<SSL_SESSION*>(d->session->_session))) {
  244. kdDebug(7029) << "Session ID is being reused." << endl;
  245. } else {
  246. kdDebug(7029) << "Error attempting to reuse session." << endl;
  247. delete d->session;
  248. d->session = 0;
  249. }
  250. }
  251. /*
  252. if (!setVerificationLogic()) {
  253. d->kossl->SSL_shutdown(d->m_ssl);
  254. d->kossl->SSL_free(d->m_ssl);
  255. d->m_ssl = 0;
  256. return -1;
  257. }
  258. */
  259. int off = SSL_OP_ALL;
  260. if (!d->lastInitTLS && !m_cfg->tlsv1())
  261. off |= SSL_OP_NO_TLSv1;
  262. if (!m_cfg->sslv3())
  263. off |= SSL_OP_NO_SSLv3;
  264. if (!m_cfg->sslv2())
  265. off |= SSL_OP_NO_SSLv2;
  266. d->kossl->_SSL_set_options(d->m_ssl, off);
  267. rc = d->kossl->SSL_set_fd(d->m_ssl, sock);
  268. if (rc == 0) {
  269. d->kossl->SSL_shutdown(d->m_ssl);
  270. d->kossl->SSL_free(d->m_ssl);
  271. d->m_ssl = 0;
  272. return rc;
  273. }
  274. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
  275. d->kossl->SSL_set_tlsext_host_name(d->m_ssl, d->proxyPeer.ascii());
  276. #endif
  277. rc = d->kossl->SSL_accept(d->m_ssl);
  278. if (rc == 1) {
  279. setConnectionInfo();
  280. setPeerInfo();
  281. kdDebug(7029) << "KSSL connected OK" << endl;
  282. } else {
  283. kdDebug(7029) << "KSSL accept failed - rc = " << rc << endl;
  284. kdDebug(7029) << " ERROR = "
  285. << d->kossl->SSL_get_error(d->m_ssl, rc) << endl;
  286. d->kossl->SSL_shutdown(d->m_ssl);
  287. d->kossl->SSL_free(d->m_ssl);
  288. d->m_ssl = 0;
  289. return -1;
  290. }
  291. if (!d->kossl->_SSL_session_reused(d->m_ssl)) {
  292. if (d->session) {
  293. kdDebug(7029) << "Session reuse failed. New session used instead." << endl;
  294. delete d->session;
  295. d->session = 0L;
  296. }
  297. }
  298. if (!d->session) {
  299. SSL_SESSION *sess = d->kossl->SSL_get1_session(d->m_ssl);
  300. if (sess) {
  301. d->session = new KSSLSession;
  302. d->session->_session = sess;
  303. }
  304. }
  305. return rc;
  306. #else
  307. return -1;
  308. #endif
  309. }
  310. int KSSL::connect(int sock) {
  311. #ifdef KSSL_HAVE_SSL
  312. // kdDebug(7029) << "KSSL connect" << endl;
  313. int rc;
  314. if (!m_bInit)
  315. return -1;
  316. d->m_ssl = d->kossl->SSL_new(d->m_ctx);
  317. if (!d->m_ssl)
  318. return -1;
  319. if (d->session) {
  320. #if OPENSSL_VERSION_NUMBER < 0x10100000L
  321. if (static_cast<SSL_SESSION*>(d->session->_session)->sess_cert == 0)
  322. {
  323. kdDebug(7029) << "Can't reuse session, no certificate." << endl;
  324. delete d->session;
  325. d->session = 0;
  326. }
  327. else
  328. #endif
  329. if (1 == d->kossl->SSL_set_session(d->m_ssl,
  330. static_cast<SSL_SESSION*>(d->session->_session))) {
  331. kdDebug(7029) << "Session ID is being reused." << endl;
  332. } else {
  333. kdDebug(7029) << "Error attempting to reuse session." << endl;
  334. delete d->session;
  335. d->session = 0;
  336. }
  337. }
  338. /*
  339. if (!setVerificationLogic()) {
  340. d->kossl->SSL_shutdown(d->m_ssl);
  341. d->kossl->SSL_free(d->m_ssl);
  342. d->m_ssl = 0;
  343. return -1;
  344. }
  345. */
  346. int off = SSL_OP_ALL;
  347. if (!d->lastInitTLS && !m_cfg->tlsv1())
  348. off |= SSL_OP_NO_TLSv1;
  349. if (!m_cfg->sslv3())
  350. off |= SSL_OP_NO_SSLv3;
  351. if (!m_cfg->sslv2())
  352. off |= SSL_OP_NO_SSLv2;
  353. d->kossl->_SSL_set_options(d->m_ssl, off);
  354. rc = d->kossl->SSL_set_fd(d->m_ssl, sock);
  355. if (rc == 0) {
  356. d->kossl->SSL_shutdown(d->m_ssl);
  357. d->kossl->SSL_free(d->m_ssl);
  358. d->m_ssl = 0;
  359. return rc;
  360. }
  361. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
  362. d->kossl->SSL_set_tlsext_host_name(d->m_ssl, d->proxyPeer.ascii());
  363. #endif
  364. connect_again:
  365. rc = d->kossl->SSL_connect(d->m_ssl);
  366. if (rc == 1) {
  367. setConnectionInfo();
  368. setPeerInfo();
  369. kdDebug(7029) << "KSSL connected OK" << endl;
  370. } else {
  371. int err = d->kossl->SSL_get_error(d->m_ssl, rc);
  372. if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
  373. // nonblocking - but we block anyways in connect() :)
  374. goto connect_again;
  375. } else {
  376. kdDebug(7029) << "KSSL connect failed - rc = "
  377. << rc << endl;
  378. kdDebug(7029) << " ERROR = "
  379. << err << endl;
  380. d->kossl->ERR_print_errors_fp(stderr);
  381. d->kossl->SSL_shutdown(d->m_ssl);
  382. d->kossl->SSL_free(d->m_ssl);
  383. d->m_ssl = 0;
  384. return -1;
  385. }
  386. }
  387. if (!d->kossl->_SSL_session_reused(d->m_ssl)) {
  388. if (d->session) {
  389. kdDebug(7029) << "Session reuse failed. New session used instead." << endl;
  390. delete d->session;
  391. d->session = 0L;
  392. }
  393. }
  394. if (!d->session) {
  395. SSL_SESSION *sess = d->kossl->SSL_get1_session(d->m_ssl);
  396. if (sess) {
  397. d->session = new KSSLSession;
  398. d->session->_session = sess;
  399. }
  400. }
  401. return rc;
  402. #else
  403. return -1;
  404. #endif
  405. }
  406. int KSSL::pending() {
  407. #ifdef KSSL_HAVE_SSL
  408. if (!m_bInit)
  409. return -1;
  410. return d->kossl->SSL_pending(d->m_ssl);
  411. #else
  412. return -1;
  413. #endif
  414. }
  415. int KSSL::peek(void *buf, int len) {
  416. #ifdef KSSL_HAVE_SSL
  417. if (!m_bInit)
  418. return -1;
  419. // FIXME: enhance to work the way read() does below, handling errors
  420. return d->kossl->SSL_peek(d->m_ssl, buf, len);
  421. #else
  422. return -1;
  423. #endif
  424. }
  425. int KSSL::read(void *buf, int len) {
  426. #ifdef KSSL_HAVE_SSL
  427. int rc = 0;
  428. int maxIters = 10;
  429. if (!m_bInit)
  430. return -1;
  431. read_again:
  432. rc = d->kossl->SSL_read(d->m_ssl, (char *)buf, len);
  433. if (rc <= 0) {
  434. int err = d->kossl->SSL_get_error(d->m_ssl, rc);
  435. if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
  436. kdDebug(7029) << "SSL read() returning 0: " << err << endl;
  437. if (maxIters-- > 0) {
  438. ::usleep(20000); // 20ms sleep
  439. goto read_again;
  440. }
  441. return 0;
  442. }
  443. kdDebug(7029) << "SSL READ ERROR: " << err << endl;
  444. if (err != SSL_ERROR_NONE &&
  445. err != SSL_ERROR_ZERO_RETURN && err != SSL_ERROR_SYSCALL) {
  446. rc = -1; // OpenSSL returns 0 on error too
  447. d->kossl->ERR_print_errors_fp(stderr);
  448. }
  449. // else if (err == SSL_ERROR_ZERO_RETURN)
  450. // rc = 0;
  451. }
  452. return rc;
  453. #else
  454. return -1;
  455. #endif
  456. }
  457. int KSSL::write(const void *buf, int len) {
  458. #ifdef KSSL_HAVE_SSL
  459. if (!m_bInit)
  460. return -1;
  461. write_again:
  462. int rc = d->kossl->SSL_write(d->m_ssl, (const char *)buf, len);
  463. if (rc <= 0) { // OpenSSL returns 0 on error too
  464. int err = d->kossl->SSL_get_error(d->m_ssl, rc);
  465. if (err == SSL_ERROR_WANT_WRITE) {
  466. ::usleep(20000); // 20ms sleep
  467. goto write_again;
  468. }
  469. kdDebug(7029) << "SSL WRITE ERROR: " << err << endl;
  470. if (err != SSL_ERROR_NONE &&
  471. err != SSL_ERROR_ZERO_RETURN && err != SSL_ERROR_SYSCALL)
  472. rc = -1;
  473. }
  474. return rc;
  475. #else
  476. return -1;
  477. #endif
  478. }
  479. bool KSSL::reconfig() {
  480. return reInitialize();
  481. }
  482. void KSSL::setAutoReconfig(bool ar) {
  483. m_bAutoReconfig = ar;
  484. }
  485. bool KSSL::setSettings(KSSLSettings *settings) {
  486. delete m_cfg;
  487. m_cfg = settings;
  488. return reconfig();
  489. }
  490. #ifdef KSSL_HAVE_SSL
  491. bool KSSL::m_bSSLWorks = true;
  492. #else
  493. bool KSSL::m_bSSLWorks = false;
  494. #endif
  495. bool KSSL::doesSSLWork() {
  496. return m_bSSLWorks;
  497. }
  498. void KSSL::setConnectionInfo() {
  499. #ifdef KSSL_HAVE_SSL
  500. SSL_CIPHER *sc;
  501. char buf[1024];
  502. buf[0] = 0; // for safety.
  503. sc = d->kossl->SSL_get_current_cipher(d->m_ssl);
  504. if (!sc) {
  505. kdDebug(7029) << "KSSL get current cipher failed - we're probably gonna crash!" << endl;
  506. return;
  507. }
  508. // set the number of bits, bits used
  509. m_ci.m_iCipherUsedBits = d->kossl->SSL_CIPHER_get_bits(sc, &(m_ci.m_iCipherBits));
  510. // set the cipher version
  511. m_ci.m_cipherVersion = d->kossl->SSL_CIPHER_get_version(sc);
  512. // set the cipher name
  513. m_ci.m_cipherName = d->kossl->SSL_CIPHER_get_name(sc);
  514. // set the cipher description
  515. m_ci.m_cipherDescription = d->kossl->SSL_CIPHER_description(sc, buf, 1023);
  516. #endif
  517. }
  518. void KSSL::setPeerInfo() {
  519. #ifdef KSSL_HAVE_SSL
  520. m_pi.setPeerHost(d->proxyPeer);
  521. m_pi.m_cert.setCert(d->kossl->SSL_get_peer_certificate(d->m_ssl));
  522. STACK_OF(X509) *xs = d->kossl->SSL_get_peer_cert_chain(d->m_ssl);
  523. if (xs)
  524. xs = reinterpret_cast<STACK_OF(X509)*>(d->kossl->OPENSSL_sk_dup(xs)); // Leak?
  525. m_pi.m_cert.setChain((void *)xs);
  526. #endif
  527. }
  528. KSSLConnectionInfo& KSSL::connectionInfo() {
  529. return m_ci;
  530. }
  531. // KDE 4: Make it const TQString &
  532. void KSSL::setPeerHost(TQString realHost) {
  533. d->proxyPeer = realHost;
  534. }
  535. // deprecated
  536. void KSSL::setProxyUse(bool, TQString, int, TQString) {
  537. }
  538. KSSLPeerInfo& KSSL::peerInfo() {
  539. return m_pi;
  540. }
  541. bool KSSL::setClientCertificate(KSSLPKCS12 *pkcs) {
  542. #ifdef KSSL_HAVE_SSL
  543. if (!pkcs || !pkcs->getCertificate())
  544. return false;
  545. int rc;
  546. X509 *x = pkcs->getCertificate()->getCert();
  547. EVP_PKEY *k = pkcs->getPrivateKey();
  548. if (!x || !k) return false;
  549. if (!pkcs->getCertificate()->x509V3Extensions().certTypeSSLClient())
  550. return false;
  551. rc = d->kossl->SSL_CTX_use_certificate(d->m_ctx, x);
  552. if (rc <= 0) {
  553. kdDebug(7029) << "KSSL - SSL_CTX_use_certificate failed. rc = " << rc << endl;
  554. return false;
  555. }
  556. rc = d->kossl->SSL_CTX_use_PrivateKey(d->m_ctx, k);
  557. if (rc <= 0) {
  558. kdDebug(7029) << "KSSL - SSL_CTX_use_PrivateKey failed. rc = " << rc << endl;
  559. return false;
  560. }
  561. return true;
  562. #else
  563. return false;
  564. #endif
  565. }
  566. const KSSLSession* KSSL::session() const {
  567. return d->session;
  568. }
  569. bool KSSL::reusingSession() const {
  570. #ifdef KSSL_HAVE_SSL
  571. return (d->m_ssl && d->kossl->_SSL_session_reused(d->m_ssl));
  572. #else
  573. return false;
  574. #endif
  575. }