00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "klone_conf.h"
00012 #include <unistd.h>
00013 #include <klone/io.h>
00014 #include <klone/ioprv.h>
00015 #include <u/libu.h>
00016 #include <openssl/ssl.h>
00017 #include <openssl/err.h>
00018
00019 struct io_ssl_s
00020 {
00021 struct io_s io;
00022 SSL *ssl;
00023 int fd;
00024 int flags;
00025 };
00026
00027 typedef struct io_ssl_s io_ssl_t;
00028
00029 static ssize_t io_ssl_read(io_ssl_t *io, char *buf, size_t size);
00030 static ssize_t io_ssl_write(io_ssl_t *io, const char *buf, size_t size);
00031
00032 int io_ssl_get_SSL(io_t *io, SSL **pssl)
00033 {
00034 io_ssl_t *io_ssl = (io_ssl_t*)io;
00035
00036 dbg_err_if(io_ssl == NULL);
00037 dbg_err_if(pssl == NULL);
00038 dbg_err_if(io_ssl->io.type != IO_TYPE_SSL);
00039
00040 dbg_err_if(io_ssl->ssl == NULL);
00041
00042 *pssl = io_ssl->ssl;
00043
00044 return 0;
00045 err:
00046 return ~0;
00047 }
00048
00049 static ssize_t io_ssl_read(io_ssl_t *io_ssl, char *buf, size_t size)
00050 {
00051 ssize_t c;
00052
00053 dbg_err_if (io_ssl == NULL);
00054 dbg_err_if (buf == NULL);
00055
00056 again:
00057 c = SSL_read(io_ssl->ssl, buf, size);
00058
00059 if(c < 0 && errno == EINTR)
00060 goto again;
00061
00062 dbg_err_if(c < 0);
00063
00064 return c;
00065 err:
00066 return -1;
00067 }
00068
00069 static ssize_t io_ssl_write(io_ssl_t *io_ssl, const char *buf, size_t size)
00070 {
00071 ssize_t c;
00072
00073 dbg_err_if (io_ssl == NULL);
00074 dbg_err_if (buf == NULL);
00075
00076 again:
00077 c = SSL_write(io_ssl->ssl, buf, size);
00078
00079 if(c < 0 && errno == EINTR)
00080 goto again;
00081
00082 dbg_err_if(c < 0);
00083
00084 return c;
00085 err:
00086 return -1;
00087 }
00088
00089
00090 static int io_ssl_close(io_ssl_t *io_ssl)
00091 {
00092 dbg_err_if(io_ssl == NULL);
00093
00094 if(io_ssl->flags & IO_FD_CLOSE && io_ssl->fd != -1)
00095 {
00096 close(io_ssl->fd);
00097 io_ssl->fd = -1;
00098 }
00099
00100 return 0;
00101 err:
00102 return ~0;
00103 }
00104
00105
00106 static int io_ssl_free(io_ssl_t *io_ssl)
00107 {
00108 dbg_err_if(io_ssl == NULL);
00109
00110 dbg_if(io_ssl_close(io_ssl));
00111
00112 if(io_ssl->ssl)
00113 {
00114 SSL_free(io_ssl->ssl);
00115 io_ssl->ssl = NULL;
00116 }
00117
00118 return 0;
00119 err:
00120 return -1;
00121 }
00122
00123 int io_ssl_create(int fd, int flags, SSL_CTX *ssl_ctx, io_t **pio)
00124 {
00125 io_ssl_t *io_ssl = NULL;
00126 int rc = 0;
00127 long vfy;
00128
00129 dbg_return_if (pio == NULL, ~0);
00130 dbg_return_if (ssl_ctx == NULL, ~0);
00131
00132 dbg_err_if(io_create(io_ssl_t, (io_t**)&io_ssl));
00133
00134 io_ssl->io.type = IO_TYPE_SSL;
00135
00136 io_ssl->fd = fd;
00137 io_ssl->flags = flags;
00138
00139 io_ssl->ssl = SSL_new(ssl_ctx);
00140 dbg_err_if(io_ssl->ssl == NULL);
00141
00142
00143 dbg_err_if(SSL_set_fd(io_ssl->ssl, fd) == 0);
00144
00145 io_ssl->io.read = (io_read_op) io_ssl_read;
00146 io_ssl->io.write = (io_write_op) io_ssl_write;
00147 io_ssl->io.close = (io_close_op) io_ssl_close;
00148 io_ssl->io.free = (io_free_op) io_ssl_free;
00149 io_ssl->io.size = 0;
00150
00151
00152 io_ssl->io.is_secure = 1;
00153
00154
00155 while((rc = SSL_accept(io_ssl->ssl)) <= 0)
00156 {
00157
00158 if(BIO_sock_should_retry(rc))
00159 continue;
00160
00161 if(SSL_get_error(io_ssl->ssl, rc) == SSL_ERROR_WANT_READ)
00162 break;
00163
00164 warn_err("SSL accept error: %d", SSL_get_error(io_ssl->ssl, rc));
00165 }
00166
00167 *pio = (io_t*)io_ssl;
00168
00169 return 0;
00170 err:
00171 if(io_ssl && io_ssl->ssl)
00172 {
00173
00174 if((vfy = SSL_get_verify_result(io_ssl->ssl)) != X509_V_OK)
00175 warn("SSL client cert verify error: %s",
00176 X509_verify_cert_error_string(vfy));
00177 SSL_set_shutdown(io_ssl->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
00178 }
00179 if(io_ssl)
00180 io_free((io_t *)io_ssl);
00181 return ~0;
00182 }