io_ssl.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
  3. * All rights reserved
  4. *
  5. * "THE BEER-WARE LICENSE" (Revision 42):
  6. * Sergey Lyubka wrote this file. As long as you retain this notice you
  7. * can do whatever you want with this stuff. If we meet some day, and you think
  8. * this stuff is worth it, you can buy me a beer in return.
  9. */
  10. #include "defs.h"
  11. #if !defined(NO_SSL)
  12. struct ssl_func ssl_sw[] = {
  13. {"SSL_free", {0}},
  14. {"SSL_accept", {0}},
  15. {"SSL_connect", {0}},
  16. {"SSL_read", {0}},
  17. {"SSL_write", {0}},
  18. {"SSL_get_error", {0}},
  19. {"SSL_set_fd", {0}},
  20. {"SSL_new", {0}},
  21. {"SSL_CTX_new", {0}},
  22. {"SSLv23_server_method", {0}},
  23. {"SSL_library_init", {0}},
  24. {"SSL_CTX_use_PrivateKey_file", {0}},
  25. {"SSL_CTX_use_certificate_file",{0}},
  26. {NULL, {0}}
  27. };
  28. void
  29. _shttpd_ssl_handshake(struct stream *stream)
  30. {
  31. int n;
  32. if ((n = SSL_accept(stream->chan.ssl.ssl)) == 1) {
  33. DBG(("handshake: SSL accepted"));
  34. stream->flags |= FLAG_SSL_ACCEPTED;
  35. } else {
  36. n = SSL_get_error(stream->chan.ssl.ssl, n);
  37. if (n != SSL_ERROR_WANT_READ && n != SSL_ERROR_WANT_WRITE)
  38. stream->flags |= FLAG_CLOSED;
  39. DBG(("SSL_accept error %d", n));
  40. }
  41. }
  42. static int
  43. read_ssl(struct stream *stream, void *buf, size_t len)
  44. {
  45. int nread = -1;
  46. assert(stream->chan.ssl.ssl != NULL);
  47. if (!(stream->flags & FLAG_SSL_ACCEPTED))
  48. _shttpd_ssl_handshake(stream);
  49. if (stream->flags & FLAG_SSL_ACCEPTED)
  50. nread = SSL_read(stream->chan.ssl.ssl, buf, len);
  51. return (nread);
  52. }
  53. static int
  54. write_ssl(struct stream *stream, const void *buf, size_t len)
  55. {
  56. assert(stream->chan.ssl.ssl != NULL);
  57. return (SSL_write(stream->chan.ssl.ssl, buf, len));
  58. }
  59. static void
  60. close_ssl(struct stream *stream)
  61. {
  62. assert(stream->chan.ssl.sock != -1);
  63. assert(stream->chan.ssl.ssl != NULL);
  64. (void) closesocket(stream->chan.ssl.sock);
  65. SSL_free(stream->chan.ssl.ssl);
  66. }
  67. const struct io_class _shttpd_io_ssl = {
  68. "ssl",
  69. read_ssl,
  70. write_ssl,
  71. close_ssl
  72. };
  73. #endif /* !NO_SSL */