version 0.1.6
[fms.git] / libs / shttpd / io_ssl.c
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
11 #include "defs.h"
12
13 #if !defined(NO_SSL)
14 struct ssl_func ssl_sw[] = {
15         {"SSL_free",                    {0}},
16         {"SSL_accept",                  {0}},
17         {"SSL_connect",                 {0}},
18         {"SSL_read",                    {0}},
19         {"SSL_write",                   {0}},
20         {"SSL_get_error",               {0}},
21         {"SSL_set_fd",                  {0}},
22         {"SSL_new",                     {0}},
23         {"SSL_CTX_new",                 {0}},
24         {"SSLv23_server_method",        {0}},
25         {"SSL_library_init",            {0}},
26         {"SSL_CTX_use_PrivateKey_file", {0}},
27         {"SSL_CTX_use_certificate_file",{0}},
28         {NULL,                          {0}}
29 };
30
31 void
32 ssl_handshake(struct stream *stream)
33 {
34         int     n;
35
36         if ((n = SSL_accept(stream->chan.ssl.ssl)) == 0) {
37                 n = SSL_get_error(stream->chan.ssl.ssl, n);
38                 if (n != SSL_ERROR_WANT_READ && n != SSL_ERROR_WANT_WRITE)
39                         stream->flags |= FLAG_CLOSED;
40                 elog(E_LOG, stream->conn, "SSL_accept error %d", n);
41         } else {
42                 DBG(("handshake: SSL accepted"));
43                 stream->flags |= FLAG_SSL_ACCEPTED;
44         }
45 }
46
47 static int
48 read_ssl(struct stream *stream, void *buf, size_t len)
49 {
50         int     nread = 0;
51
52         assert(stream->chan.ssl.ssl != NULL);
53
54         if (!(stream->flags & FLAG_SSL_ACCEPTED))
55                 ssl_handshake(stream);
56
57         if (stream->flags & FLAG_SSL_ACCEPTED)
58                 nread = SSL_read(stream->chan.ssl.ssl, buf, len);
59
60         return (nread);
61 }
62
63 static int
64 write_ssl(struct stream *stream, const void *buf, size_t len)
65 {
66         assert(stream->chan.ssl.ssl != NULL);
67         return (SSL_write(stream->chan.ssl.ssl, buf, len));
68 }
69
70 static void
71 close_ssl(struct stream *stream)
72 {
73         assert(stream->chan.ssl.sock != -1);
74         assert(stream->chan.ssl.ssl != NULL);
75         (void) closesocket(stream->chan.ssl.sock);
76         SSL_free(stream->chan.ssl.ssl);
77 }
78
79 const struct io_class   io_ssl =  {
80         "ssl",
81         read_ssl,
82         write_ssl,
83         close_ssl
84 };
85 #endif /* !NO_SSL */