conn-ssl.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917
  1. /*
  2. * ngIRCd -- The Next Generation IRC Daemon
  3. * Copyright (c)2005-2008 Florian Westphal (fw@strlen.de).
  4. * Copyright (c)2008-2014 Alexander Barton (alex@barton.de) and Contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. * Please read the file COPYING, README and AUTHORS for more information.
  11. */
  12. #include "portab.h"
  13. /**
  14. * @file
  15. * SSL wrapper functions
  16. */
  17. #include "conf-ssl.h"
  18. #ifdef SSL_SUPPORT
  19. #include "io.h"
  20. #include <assert.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #include <errno.h>
  25. #define CONN_MODULE
  26. #include "conn.h"
  27. #include "conf.h"
  28. #include "conn-func.h"
  29. #include "conn-ssl.h"
  30. #include "log.h"
  31. #include "defines.h"
  32. extern struct SSLOptions Conf_SSLOptions;
  33. #ifdef HAVE_LIBSSL
  34. #include <openssl/err.h>
  35. #include <openssl/rand.h>
  36. #include <openssl/dh.h>
  37. static SSL_CTX * ssl_ctx;
  38. static DH *dh_params;
  39. static bool ConnSSL_LoadServerKey_openssl PARAMS(( SSL_CTX *c ));
  40. #endif
  41. #ifdef HAVE_LIBGNUTLS
  42. #include <sys/types.h>
  43. #include <sys/stat.h>
  44. #include <fcntl.h>
  45. #include <unistd.h>
  46. #include <gnutls/x509.h>
  47. #define DH_BITS 2048
  48. #define DH_BITS_MIN 1024
  49. #define MAX_HASH_SIZE 64 /* from gnutls-int.h */
  50. static gnutls_certificate_credentials_t x509_cred;
  51. static gnutls_dh_params_t dh_params;
  52. static gnutls_priority_t priorities_cache;
  53. static bool ConnSSL_LoadServerKey_gnutls PARAMS(( void ));
  54. #endif
  55. #define SHA256_STRING_LEN (32 * 2 + 1)
  56. static bool ConnSSL_Init_SSL PARAMS(( CONNECTION *c ));
  57. static int ConnectAccept PARAMS(( CONNECTION *c, bool connect ));
  58. static int ConnSSL_HandleError PARAMS(( CONNECTION *c, const int code, const char *fname ));
  59. #ifdef HAVE_LIBGNUTLS
  60. static char * openreadclose(const char *name, size_t *len)
  61. {
  62. char *buf = NULL;
  63. struct stat s;
  64. ssize_t br;
  65. int fd = open(name, O_RDONLY);
  66. if (fd < 0) {
  67. Log(LOG_ERR, "Could not open %s: %s", name, strerror(errno));
  68. return NULL;
  69. }
  70. if (fstat(fd, &s)) {
  71. Log(LOG_ERR, "Could not fstat %s: %s", name, strerror(errno));
  72. goto out;
  73. }
  74. if (!S_ISREG(s.st_mode)) {
  75. Log(LOG_ERR, "%s: Not a regular file", name);
  76. goto out;
  77. }
  78. if (s.st_size <= 0) {
  79. Log(LOG_ERR, "%s: invalid file length (size %ld <= 0)", name, (long) s.st_size);
  80. goto out;
  81. }
  82. buf = malloc(s.st_size);
  83. if (!buf) {
  84. Log(LOG_ERR, "Could not malloc %lu bytes for file %s: %s", s.st_size, name, strerror(errno));
  85. goto out;
  86. }
  87. br = read(fd, buf, s.st_size);
  88. if (br != (ssize_t)s.st_size) {
  89. Log(LOG_ERR, "Could not read file %s: read returned %ld, expected %ld: %s",
  90. name, (long) br, (long) s.st_size, br == -1 ? strerror(errno):"short read?!");
  91. memset(buf, 0, s.st_size);
  92. free(buf);
  93. buf = NULL;
  94. } else {
  95. *len = br;
  96. }
  97. out:
  98. close(fd);
  99. return buf;
  100. }
  101. #endif
  102. #ifdef HAVE_LIBSSL
  103. /**
  104. * Log OpenSSL error message.
  105. *
  106. * @param msg The error message.
  107. * @param info Additional information text or NULL.
  108. */
  109. static void
  110. LogOpenSSLError(const char *error, const char *info)
  111. {
  112. unsigned long err = ERR_get_error();
  113. char * errmsg = err
  114. ? ERR_error_string(err, NULL)
  115. : "Unable to determine error";
  116. assert(error != NULL);
  117. if (info)
  118. Log(LOG_ERR, "%s: %s (%s)", error, info, errmsg);
  119. else
  120. Log(LOG_ERR, "%s: %s", error, errmsg);
  121. }
  122. static int
  123. pem_passwd_cb(char *buf, int size, int rwflag, void *password)
  124. {
  125. array *pass = password;
  126. int passlen;
  127. (void)rwflag; /* rwflag is unused if DEBUG is not set. */
  128. assert(rwflag == 0); /* 0 -> callback used for decryption.
  129. * See SSL_CTX_set_default_passwd_cb(3) */
  130. passlen = (int) array_bytes(pass);
  131. LogDebug("pem_passwd_cb buf size %d, array size %d", size, passlen);
  132. assert(passlen >= 0);
  133. if (passlen <= 0) {
  134. Log(LOG_ERR, "PEM password required but not set [in pem_passwd_cb()]!");
  135. return 0;
  136. }
  137. size = passlen > size ? size : passlen;
  138. memcpy(buf, (char *)(array_start(pass)), size);
  139. return size;
  140. }
  141. static int
  142. Verify_openssl(UNUSED int preverify_ok, UNUSED X509_STORE_CTX *x509_ctx)
  143. {
  144. return 1;
  145. }
  146. #endif
  147. static bool
  148. Load_DH_params(void)
  149. {
  150. #ifdef HAVE_LIBSSL
  151. FILE *fp;
  152. bool ret = true;
  153. if (!Conf_SSLOptions.DHFile) {
  154. Log(LOG_NOTICE, "Configuration option \"DHFile\" not set!");
  155. return false;
  156. }
  157. fp = fopen(Conf_SSLOptions.DHFile, "r");
  158. if (!fp) {
  159. Log(LOG_ERR, "%s: %s", Conf_SSLOptions.DHFile, strerror(errno));
  160. return false;
  161. }
  162. dh_params = PEM_read_DHparams(fp, NULL, NULL, NULL);
  163. if (!dh_params) {
  164. Log(LOG_ERR, "%s: Failed to read SSL DH parameters!",
  165. Conf_SSLOptions.DHFile);
  166. ret = false;
  167. }
  168. fclose(fp);
  169. return ret;
  170. #endif
  171. #ifdef HAVE_LIBGNUTLS
  172. bool need_dhgenerate = true;
  173. int err;
  174. gnutls_dh_params_t tmp_dh_params;
  175. err = gnutls_dh_params_init(&tmp_dh_params);
  176. if (err < 0) {
  177. Log(LOG_ERR, "Failed to initialize SSL DH parameters: %s",
  178. gnutls_strerror(err));
  179. return false;
  180. }
  181. if (Conf_SSLOptions.DHFile) {
  182. gnutls_datum_t dhparms;
  183. size_t size;
  184. dhparms.data = (unsigned char *) openreadclose(Conf_SSLOptions.DHFile, &size);
  185. if (dhparms.data) {
  186. dhparms.size = size;
  187. err = gnutls_dh_params_import_pkcs3(tmp_dh_params, &dhparms, GNUTLS_X509_FMT_PEM);
  188. if (err == 0)
  189. need_dhgenerate = false;
  190. else
  191. Log(LOG_ERR,
  192. "Failed to initialize SSL DH parameters: %s",
  193. gnutls_strerror(err));
  194. memset(dhparms.data, 0, size);
  195. free(dhparms.data);
  196. }
  197. }
  198. if (need_dhgenerate) {
  199. Log(LOG_WARNING,
  200. "DHFile not set, generating %u bit DH parameters. This may take a while ...",
  201. DH_BITS);
  202. err = gnutls_dh_params_generate2(tmp_dh_params, DH_BITS);
  203. if (err < 0) {
  204. Log(LOG_ERR, "Failed to generate SSL DH parameters: %s",
  205. gnutls_strerror(err));
  206. return false;
  207. }
  208. }
  209. dh_params = tmp_dh_params;
  210. return true;
  211. #endif
  212. }
  213. void ConnSSL_Free(CONNECTION *c)
  214. {
  215. #ifdef HAVE_LIBSSL
  216. SSL *ssl = c->ssl_state.ssl;
  217. if (ssl) {
  218. SSL_shutdown(ssl);
  219. SSL_free(ssl);
  220. c->ssl_state.ssl = NULL;
  221. if (c->ssl_state.fingerprint) {
  222. free(c->ssl_state.fingerprint);
  223. c->ssl_state.fingerprint = NULL;
  224. }
  225. }
  226. #endif
  227. #ifdef HAVE_LIBGNUTLS
  228. gnutls_session_t sess = c->ssl_state.gnutls_session;
  229. if (Conn_OPTION_ISSET(c, CONN_SSL)) {
  230. gnutls_bye(sess, GNUTLS_SHUT_RDWR);
  231. gnutls_deinit(sess);
  232. }
  233. #endif
  234. assert(Conn_OPTION_ISSET(c, CONN_SSL));
  235. /* can't just set bitmask to 0 -- there are other, non-ssl related flags, e.g. CONN_ZIP. */
  236. Conn_OPTION_DEL(c, CONN_SSL_FLAGS_ALL);
  237. }
  238. bool
  239. ConnSSL_InitLibrary( void )
  240. {
  241. if (!Conf_SSLInUse()) {
  242. LogDebug("SSL not in use, skipping initialization.");
  243. return true;
  244. }
  245. #ifdef HAVE_LIBSSL
  246. SSL_CTX *newctx;
  247. #if OPENSSL_API_COMPAT < 0x10100000L
  248. if (!ssl_ctx) {
  249. SSL_library_init();
  250. SSL_load_error_strings();
  251. }
  252. #endif
  253. if (!RAND_status()) {
  254. Log(LOG_ERR, "OpenSSL PRNG not seeded: /dev/urandom missing?");
  255. /*
  256. * it is probably best to fail and let the user install EGD or
  257. * a similar program if no kernel random device is available.
  258. * According to OpenSSL RAND_egd(3): "The automatic query of
  259. * /var/run/egd-pool et al was added in OpenSSL 0.9.7";
  260. * so it makes little sense to deal with PRNGD seeding ourselves.
  261. */
  262. array_free(&Conf_SSLOptions.ListenPorts);
  263. return false;
  264. }
  265. newctx = SSL_CTX_new(SSLv23_method());
  266. if (!newctx) {
  267. LogOpenSSLError("Failed to create SSL context", NULL);
  268. array_free(&Conf_SSLOptions.ListenPorts);
  269. return false;
  270. }
  271. if (!ConnSSL_LoadServerKey_openssl(newctx))
  272. goto out;
  273. if (SSL_CTX_set_cipher_list(newctx, Conf_SSLOptions.CipherList) == 0) {
  274. Log(LOG_ERR, "Failed to apply OpenSSL cipher list \"%s\"!",
  275. Conf_SSLOptions.CipherList);
  276. goto out;
  277. }
  278. SSL_CTX_set_session_id_context(newctx, (unsigned char *)"ngircd", 6);
  279. SSL_CTX_set_options(newctx, SSL_OP_SINGLE_DH_USE|SSL_OP_NO_SSLv2);
  280. SSL_CTX_set_mode(newctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
  281. SSL_CTX_set_verify(newctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
  282. Verify_openssl);
  283. SSL_CTX_free(ssl_ctx);
  284. ssl_ctx = newctx;
  285. Log(LOG_INFO, "%s initialized.", OpenSSL_version(OPENSSL_VERSION));
  286. return true;
  287. out:
  288. SSL_CTX_free(newctx);
  289. array_free(&Conf_SSLOptions.ListenPorts);
  290. return false;
  291. #endif
  292. #ifdef HAVE_LIBGNUTLS
  293. int err;
  294. static bool initialized;
  295. if (initialized) {
  296. /* TODO: cannot reload gnutls keys: can't simply free x509
  297. * context -- it may still be in use */
  298. return false;
  299. }
  300. err = gnutls_global_init();
  301. if (err) {
  302. Log(LOG_ERR, "Failed to initialize GnuTLS: %s",
  303. gnutls_strerror(err));
  304. goto out;
  305. }
  306. if (!ConnSSL_LoadServerKey_gnutls())
  307. goto out;
  308. if (gnutls_priority_init(&priorities_cache, Conf_SSLOptions.CipherList,
  309. NULL) != GNUTLS_E_SUCCESS) {
  310. Log(LOG_ERR,
  311. "Failed to apply GnuTLS cipher list \"%s\"!",
  312. Conf_SSLOptions.CipherList);
  313. goto out;
  314. }
  315. Log(LOG_INFO, "GnuTLS %s initialized.", gnutls_check_version(NULL));
  316. initialized = true;
  317. return true;
  318. out:
  319. array_free(&Conf_SSLOptions.ListenPorts);
  320. return false;
  321. #endif
  322. }
  323. #ifdef HAVE_LIBGNUTLS
  324. static bool
  325. ConnSSL_LoadServerKey_gnutls(void)
  326. {
  327. int err;
  328. const char *cert_file;
  329. err = gnutls_certificate_allocate_credentials(&x509_cred);
  330. if (err < 0) {
  331. Log(LOG_ERR, "Failed to allocate certificate credentials: %s",
  332. gnutls_strerror(err));
  333. return false;
  334. }
  335. cert_file = Conf_SSLOptions.CertFile ? Conf_SSLOptions.CertFile:Conf_SSLOptions.KeyFile;
  336. if (!cert_file) {
  337. Log(LOG_ERR, "No SSL server key configured!");
  338. return false;
  339. }
  340. if (array_bytes(&Conf_SSLOptions.KeyFilePassword))
  341. Log(LOG_WARNING,
  342. "Ignoring SSL \"KeyFilePassword\": Not supported by GnuTLS.");
  343. if (!Load_DH_params())
  344. return false;
  345. gnutls_certificate_set_dh_params(x509_cred, dh_params);
  346. err = gnutls_certificate_set_x509_key_file(x509_cred, cert_file, Conf_SSLOptions.KeyFile, GNUTLS_X509_FMT_PEM);
  347. if (err < 0) {
  348. Log(LOG_ERR,
  349. "Failed to set certificate key file (cert %s, key %s): %s",
  350. cert_file,
  351. Conf_SSLOptions.KeyFile ? Conf_SSLOptions.KeyFile : "(NULL)",
  352. gnutls_strerror(err));
  353. return false;
  354. }
  355. return true;
  356. }
  357. #endif
  358. #ifdef HAVE_LIBSSL
  359. static bool
  360. ConnSSL_LoadServerKey_openssl(SSL_CTX *ctx)
  361. {
  362. char *cert_key;
  363. assert(ctx);
  364. if (!Conf_SSLOptions.KeyFile) {
  365. Log(LOG_ERR, "No SSL server key configured!");
  366. return false;
  367. }
  368. SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
  369. SSL_CTX_set_default_passwd_cb_userdata(ctx, &Conf_SSLOptions.KeyFilePassword);
  370. if (SSL_CTX_use_PrivateKey_file(ctx, Conf_SSLOptions.KeyFile, SSL_FILETYPE_PEM) != 1) {
  371. array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
  372. LogOpenSSLError("Failed to add private key", Conf_SSLOptions.KeyFile);
  373. return false;
  374. }
  375. cert_key = Conf_SSLOptions.CertFile ? Conf_SSLOptions.CertFile:Conf_SSLOptions.KeyFile;
  376. if (SSL_CTX_use_certificate_chain_file(ctx, cert_key) != 1) {
  377. array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
  378. LogOpenSSLError("Failed to load certificate chain", cert_key);
  379. return false;
  380. }
  381. array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
  382. if (!SSL_CTX_check_private_key(ctx)) {
  383. LogOpenSSLError("Server private key does not match certificate", NULL);
  384. return false;
  385. }
  386. if (Load_DH_params()) {
  387. if (SSL_CTX_set_tmp_dh(ctx, dh_params) != 1)
  388. LogOpenSSLError("Error setting DH parameters", Conf_SSLOptions.DHFile);
  389. /* don't return false here: the non-DH modes will still work */
  390. DH_free(dh_params);
  391. dh_params = NULL;
  392. }
  393. return true;
  394. }
  395. #endif
  396. static bool
  397. ConnSSL_Init_SSL(CONNECTION *c)
  398. {
  399. int ret;
  400. LogDebug("Initializing SSL ...");
  401. assert(c != NULL);
  402. #ifdef HAVE_LIBSSL
  403. if (!ssl_ctx) {
  404. Log(LOG_ERR,
  405. "Can't initialize SSL context, OpenSSL initialization failed at startup!");
  406. return false;
  407. }
  408. assert(c->ssl_state.ssl == NULL);
  409. assert(c->ssl_state.fingerprint == NULL);
  410. c->ssl_state.ssl = SSL_new(ssl_ctx);
  411. if (!c->ssl_state.ssl) {
  412. LogOpenSSLError("Failed to create SSL structure", NULL);
  413. return false;
  414. }
  415. Conn_OPTION_ADD(c, CONN_SSL);
  416. ret = SSL_set_fd(c->ssl_state.ssl, c->sock);
  417. if (ret != 1) {
  418. LogOpenSSLError("Failed to set SSL file descriptor", NULL);
  419. ConnSSL_Free(c);
  420. return false;
  421. }
  422. #endif
  423. #ifdef HAVE_LIBGNUTLS
  424. Conn_OPTION_ADD(c, CONN_SSL);
  425. ret = gnutls_priority_set(c->ssl_state.gnutls_session, priorities_cache);
  426. if (ret != GNUTLS_E_SUCCESS) {
  427. Log(LOG_ERR, "Failed to set GnuTLS session priorities: %s",
  428. gnutls_strerror(ret));
  429. ConnSSL_Free(c);
  430. return false;
  431. }
  432. /*
  433. * The intermediate (long) cast is here to avoid a warning like:
  434. * "cast to pointer from integer of different size" on 64-bit platforms.
  435. * There doesn't seem to be an alternate GNUTLS API we could use instead, see e.g.
  436. * http://www.mail-archive.com/help-gnutls@gnu.org/msg00286.html
  437. */
  438. gnutls_transport_set_ptr(c->ssl_state.gnutls_session,
  439. (gnutls_transport_ptr_t) (long) c->sock);
  440. gnutls_certificate_server_set_request(c->ssl_state.gnutls_session,
  441. GNUTLS_CERT_REQUEST);
  442. ret = gnutls_credentials_set(c->ssl_state.gnutls_session,
  443. GNUTLS_CRD_CERTIFICATE, x509_cred);
  444. if (ret != 0) {
  445. Log(LOG_ERR, "Failed to set SSL credentials: %s",
  446. gnutls_strerror(ret));
  447. ConnSSL_Free(c);
  448. return false;
  449. }
  450. gnutls_dh_set_prime_bits(c->ssl_state.gnutls_session, DH_BITS_MIN);
  451. #endif
  452. return true;
  453. }
  454. bool
  455. ConnSSL_PrepareConnect(CONNECTION *c, UNUSED CONF_SERVER *s)
  456. {
  457. bool ret;
  458. #ifdef HAVE_LIBGNUTLS
  459. int err;
  460. err = gnutls_init(&c->ssl_state.gnutls_session, GNUTLS_CLIENT);
  461. if (err) {
  462. Log(LOG_ERR, "Failed to initialize new SSL session: %s",
  463. gnutls_strerror(err));
  464. return false;
  465. }
  466. #endif
  467. ret = ConnSSL_Init_SSL(c);
  468. if (!ret)
  469. return false;
  470. Conn_OPTION_ADD(c, CONN_SSL_CONNECT);
  471. #ifdef HAVE_LIBSSL
  472. assert(c->ssl_state.ssl);
  473. SSL_set_verify(c->ssl_state.ssl, SSL_VERIFY_NONE, NULL);
  474. #endif
  475. return true;
  476. }
  477. /**
  478. * Check and handle error return codes after failed calls to SSL functions.
  479. *
  480. * OpenSSL:
  481. * SSL_connect(), SSL_accept(), SSL_do_handshake(), SSL_read(), SSL_peek(), or
  482. * SSL_write() on ssl.
  483. *
  484. * GnuTLS:
  485. * gnutlsssl_read(), gnutls_write() or gnutls_handshake().
  486. *
  487. * @param c The connection handle.
  488. * @prarm code The return code.
  489. * @param fname The name of the function in which the error occurred.
  490. * @return -1 on fatal errors, 0 if we can try again later.
  491. */
  492. static int
  493. ConnSSL_HandleError(CONNECTION * c, const int code, const char *fname)
  494. {
  495. #ifdef HAVE_LIBSSL
  496. int ret = SSL_ERROR_SYSCALL;
  497. unsigned long sslerr;
  498. int real_errno = errno;
  499. ret = SSL_get_error(c->ssl_state.ssl, code);
  500. switch (ret) {
  501. case SSL_ERROR_WANT_READ:
  502. io_event_del(c->sock, IO_WANTWRITE);
  503. Conn_OPTION_ADD(c, CONN_SSL_WANT_READ);
  504. return 0; /* try again later */
  505. case SSL_ERROR_WANT_WRITE:
  506. io_event_del(c->sock, IO_WANTREAD);
  507. Conn_OPTION_ADD(c, CONN_SSL_WANT_WRITE); /* fall through */
  508. case SSL_ERROR_NONE:
  509. return 0; /* try again later */
  510. case SSL_ERROR_ZERO_RETURN:
  511. LogDebug("SSL connection shut down normally.");
  512. break;
  513. case SSL_ERROR_SYSCALL:
  514. /* SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT,
  515. * and SSL_ERROR_WANT_X509_LOOKUP */
  516. sslerr = ERR_get_error();
  517. if (sslerr) {
  518. Log(LOG_ERR, "SSL error: %s [in %s()]!",
  519. ERR_error_string(sslerr, NULL), fname);
  520. } else {
  521. switch (code) { /* EOF that violated protocol */
  522. case 0:
  523. Log(LOG_ERR,
  524. "SSL error, client disconnected [in %s()]!",
  525. fname);
  526. break;
  527. case -1: /* low level socket I/O error, check errno */
  528. Log(LOG_ERR, "SSL error: %s [in %s()]!",
  529. strerror(real_errno), fname);
  530. }
  531. }
  532. break;
  533. case SSL_ERROR_SSL:
  534. LogOpenSSLError("SSL protocol error", fname);
  535. break;
  536. default:
  537. Log(LOG_ERR, "Unknown SSL error %d [in %s()]!", ret, fname);
  538. }
  539. ConnSSL_Free(c);
  540. return -1;
  541. #endif
  542. #ifdef HAVE_LIBGNUTLS
  543. switch (code) {
  544. case GNUTLS_E_AGAIN:
  545. case GNUTLS_E_INTERRUPTED:
  546. if (gnutls_record_get_direction(c->ssl_state.gnutls_session)) {
  547. Conn_OPTION_ADD(c, CONN_SSL_WANT_WRITE);
  548. io_event_del(c->sock, IO_WANTREAD);
  549. } else {
  550. Conn_OPTION_ADD(c, CONN_SSL_WANT_READ);
  551. io_event_del(c->sock, IO_WANTWRITE);
  552. }
  553. break;
  554. default:
  555. assert(code < 0);
  556. if (gnutls_error_is_fatal(code)) {
  557. Log(LOG_ERR, "SSL error: %s [%s].",
  558. gnutls_strerror(code), fname);
  559. ConnSSL_Free(c);
  560. return -1;
  561. }
  562. }
  563. return 0;
  564. #endif
  565. }
  566. static void
  567. ConnSSL_LogCertInfo( CONNECTION *c )
  568. {
  569. #ifdef HAVE_LIBSSL
  570. SSL *ssl = c->ssl_state.ssl;
  571. assert(ssl);
  572. Log(LOG_INFO, "Connection %d: initialized %s using cipher %s.",
  573. c->sock, SSL_get_version(ssl), SSL_get_cipher(ssl));
  574. #endif
  575. #ifdef HAVE_LIBGNUTLS
  576. gnutls_session_t sess = c->ssl_state.gnutls_session;
  577. gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(sess);
  578. Log(LOG_INFO, "Connection %d: initialized %s using cipher %s-%s.",
  579. c->sock,
  580. gnutls_protocol_get_name(gnutls_protocol_get_version(sess)),
  581. gnutls_cipher_get_name(cipher),
  582. gnutls_mac_get_name(gnutls_mac_get(sess)));
  583. #endif
  584. }
  585. /*
  586. Accept incoming SSL connection.
  587. Return Values:
  588. 1: SSL Connection established
  589. 0: try again
  590. -1: SSL Connection not established due to fatal error.
  591. */
  592. int
  593. ConnSSL_Accept( CONNECTION *c )
  594. {
  595. assert(c != NULL);
  596. if (!Conn_OPTION_ISSET(c, CONN_SSL)) {
  597. #ifdef HAVE_LIBGNUTLS
  598. int err = gnutls_init(&c->ssl_state.gnutls_session, GNUTLS_SERVER);
  599. if (err) {
  600. Log(LOG_ERR, "Failed to initialize new SSL session: %s",
  601. gnutls_strerror(err));
  602. return false;
  603. }
  604. #endif
  605. if (!ConnSSL_Init_SSL(c))
  606. return -1;
  607. }
  608. return ConnectAccept(c, false );
  609. }
  610. int
  611. ConnSSL_Connect( CONNECTION *c )
  612. {
  613. assert(c != NULL);
  614. #ifdef HAVE_LIBSSL
  615. assert(c->ssl_state.ssl);
  616. #endif
  617. assert(Conn_OPTION_ISSET(c, CONN_SSL));
  618. return ConnectAccept(c, true);
  619. }
  620. static int
  621. ConnSSL_InitCertFp( CONNECTION *c )
  622. {
  623. const char hex[] = "0123456789abcdef";
  624. int i;
  625. #ifdef HAVE_LIBSSL
  626. unsigned char digest[EVP_MAX_MD_SIZE];
  627. unsigned int digest_size;
  628. X509 *cert;
  629. cert = SSL_get_peer_certificate(c->ssl_state.ssl);
  630. if (!cert)
  631. return 0;
  632. if (!X509_digest(cert, EVP_sha256(), digest, &digest_size)) {
  633. X509_free(cert);
  634. return 0;
  635. }
  636. X509_free(cert);
  637. #endif /* HAVE_LIBSSL */
  638. #ifdef HAVE_LIBGNUTLS
  639. gnutls_x509_crt_t cert;
  640. unsigned int cert_list_size;
  641. const gnutls_datum_t *cert_list;
  642. unsigned char digest[MAX_HASH_SIZE];
  643. size_t digest_size;
  644. if (gnutls_certificate_type_get(c->ssl_state.gnutls_session) !=
  645. GNUTLS_CRT_X509)
  646. return 0;
  647. if (gnutls_x509_crt_init(&cert) != GNUTLS_E_SUCCESS)
  648. return 0;
  649. cert_list_size = 0;
  650. cert_list = gnutls_certificate_get_peers(c->ssl_state.gnutls_session,
  651. &cert_list_size);
  652. if (!cert_list) {
  653. gnutls_x509_crt_deinit(cert);
  654. return 0;
  655. }
  656. if (gnutls_x509_crt_import(cert, &cert_list[0],
  657. GNUTLS_X509_FMT_DER) != GNUTLS_E_SUCCESS) {
  658. gnutls_x509_crt_deinit(cert);
  659. return 0;
  660. }
  661. digest_size = sizeof(digest);
  662. if (gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA256, digest,
  663. &digest_size)) {
  664. gnutls_x509_crt_deinit(cert);
  665. return 0;
  666. }
  667. gnutls_x509_crt_deinit(cert);
  668. #endif /* HAVE_LIBGNUTLS */
  669. assert(c->ssl_state.fingerprint == NULL);
  670. c->ssl_state.fingerprint = malloc(SHA256_STRING_LEN);
  671. if (!c->ssl_state.fingerprint)
  672. return 0;
  673. for (i = 0; i < (int)digest_size; i++) {
  674. c->ssl_state.fingerprint[i * 2] = hex[digest[i] / 16];
  675. c->ssl_state.fingerprint[i * 2 + 1] = hex[digest[i] % 16];
  676. }
  677. c->ssl_state.fingerprint[i * 2] = '\0';
  678. return 1;
  679. }
  680. /* accept/connect wrapper. if connect is true, connect to peer, otherwise wait for incoming connection */
  681. static int
  682. ConnectAccept( CONNECTION *c, bool connect)
  683. {
  684. int ret;
  685. #ifdef HAVE_LIBSSL
  686. SSL *ssl = c->ssl_state.ssl;
  687. assert(ssl != NULL);
  688. ret = connect ? SSL_connect(ssl) : SSL_accept(ssl);
  689. if (1 != ret)
  690. return ConnSSL_HandleError(c, ret, connect ? "SSL_connect": "SSL_accept");
  691. #endif
  692. #ifdef HAVE_LIBGNUTLS
  693. (void) connect;
  694. ret = gnutls_handshake(c->ssl_state.gnutls_session);
  695. if (ret)
  696. return ConnSSL_HandleError(c, ret, "gnutls_handshake");
  697. #endif /* _GNUTLS */
  698. (void)ConnSSL_InitCertFp(c);
  699. Conn_OPTION_DEL(c, (CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ|CONN_SSL_CONNECT));
  700. ConnSSL_LogCertInfo(c);
  701. Conn_StartLogin(CONNECTION2ID(c));
  702. return 1;
  703. }
  704. ssize_t
  705. ConnSSL_Write(CONNECTION *c, const void *buf, size_t count)
  706. {
  707. ssize_t bw;
  708. Conn_OPTION_DEL(c, CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ);
  709. assert(count > 0);
  710. #ifdef HAVE_LIBSSL
  711. bw = (ssize_t) SSL_write(c->ssl_state.ssl, buf, count);
  712. #endif
  713. #ifdef HAVE_LIBGNUTLS
  714. bw = gnutls_write(c->ssl_state.gnutls_session, buf, count);
  715. #endif
  716. if (bw > 0)
  717. return bw;
  718. if (ConnSSL_HandleError( c, bw, "ConnSSL_Write") == 0)
  719. errno = EAGAIN; /* try again */
  720. return -1;
  721. }
  722. ssize_t
  723. ConnSSL_Read(CONNECTION *c, void * buf, size_t count)
  724. {
  725. ssize_t br;
  726. Conn_OPTION_DEL(c, CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ);
  727. #ifdef HAVE_LIBSSL
  728. br = (ssize_t) SSL_read(c->ssl_state.ssl, buf, count);
  729. if (br > 0) /* on EOF we have to call ConnSSL_HandleError(), see SSL_read(3) */
  730. return br;
  731. #endif
  732. #ifdef HAVE_LIBGNUTLS
  733. br = gnutls_read(c->ssl_state.gnutls_session, buf, count);
  734. if (br >= 0) /* on EOF we must _not_ call ConnSSL_HandleError, see gnutls_record_recv(3) */
  735. return br;
  736. #endif
  737. /* error on read: switch ConnSSL_HandleError() return values -> 0 is "try again", so return -1 and set EAGAIN */
  738. if (ConnSSL_HandleError(c, br, "ConnSSL_Read") == 0) {
  739. errno = EAGAIN;
  740. return -1;
  741. }
  742. return 0;
  743. }
  744. bool
  745. ConnSSL_GetCipherInfo(CONNECTION *c, char *buf, size_t len)
  746. {
  747. #ifdef HAVE_LIBSSL
  748. char *nl;
  749. SSL *ssl = c->ssl_state.ssl;
  750. if (!ssl)
  751. return false;
  752. *buf = 0;
  753. SSL_CIPHER_description(SSL_get_current_cipher(ssl), buf, len);
  754. nl = strchr(buf, '\n');
  755. if (nl)
  756. *nl = 0;
  757. return true;
  758. #endif
  759. #ifdef HAVE_LIBGNUTLS
  760. if (Conn_OPTION_ISSET(c, CONN_SSL)) {
  761. const char *name_cipher, *name_mac, *name_proto, *name_keyexchange;
  762. unsigned keysize;
  763. gnutls_session_t sess = c->ssl_state.gnutls_session;
  764. gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(sess);
  765. name_cipher = gnutls_cipher_get_name(cipher);
  766. name_mac = gnutls_mac_get_name(gnutls_mac_get(sess));
  767. keysize = gnutls_cipher_get_key_size(cipher) * 8;
  768. name_proto = gnutls_protocol_get_name(gnutls_protocol_get_version(sess));
  769. name_keyexchange = gnutls_kx_get_name(gnutls_kx_get(sess));
  770. return snprintf(buf, len, "%s-%s%15s Kx=%s Enc=%s(%u) Mac=%s",
  771. name_cipher, name_mac, name_proto, name_keyexchange, name_cipher, keysize, name_mac) > 0;
  772. }
  773. return false;
  774. #endif
  775. }
  776. char *
  777. ConnSSL_GetCertFp(CONNECTION *c)
  778. {
  779. return c->ssl_state.fingerprint;
  780. }
  781. bool
  782. ConnSSL_SetCertFp(CONNECTION *c, const char *fingerprint)
  783. {
  784. assert (c != NULL);
  785. c->ssl_state.fingerprint = strndup(fingerprint, SHA256_STRING_LEN - 1);
  786. return c->ssl_state.fingerprint != NULL;
  787. }
  788. #else
  789. bool
  790. ConnSSL_InitLibrary(void)
  791. {
  792. return true;
  793. }
  794. #endif /* SSL_SUPPORT */
  795. /* -eof- */