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 static int io_ssl_term(io_ssl_t *io);
00032
00033 int io_ssl_get_SSL(io_t *io, SSL **pssl)
00034 {
00035 io_ssl_t *io_ssl = (io_ssl_t*)io;
00036
00037 dbg_err_if(io_ssl == NULL);
00038 dbg_err_if(pssl == NULL);
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 if(c < 0 && (errno == EINTR || errno == EAGAIN))
00059 goto again;
00060
00061 dbg_err_if(c < 0);
00062
00063 return c;
00064 err:
00065 return -1;
00066 }
00067
00068 static ssize_t io_ssl_write(io_ssl_t *io_ssl, const char *buf, size_t size)
00069 {
00070 ssize_t c;
00071
00072 dbg_err_if (io_ssl == NULL);
00073 dbg_err_if (buf == NULL);
00074
00075 again:
00076 c = SSL_write(io_ssl->ssl, buf, size);
00077 if(c < 0 && (errno == EINTR || errno == EAGAIN))
00078 goto again;
00079
00080 dbg_err_if(c < 0);
00081
00082 return c;
00083 err:
00084 return -1;
00085 }
00086
00087 static int io_ssl_term(io_ssl_t *io_ssl)
00088 {
00089 dbg_err_if(io_ssl == NULL);
00090
00091
00092
00093
00094
00095
00096 if(io_ssl->flags & IO_FD_CLOSE)
00097 {
00098 close(io_ssl->fd);
00099 io_ssl->fd = -1;
00100 }
00101
00102 return 0;
00103 err:
00104 return -1;
00105 }
00106
00107 int io_ssl_create(int fd, int flags, SSL_CTX *ssl_ctx, io_t **pio)
00108 {
00109 io_ssl_t *io_ssl = NULL;
00110 int rc = 0;
00111 long vfy;
00112
00113 dbg_return_if (pio == NULL, ~0);
00114 dbg_return_if (ssl_ctx == NULL, ~0);
00115
00116 dbg_err_if(io_create(io_ssl_t, (io_t**)&io_ssl));
00117
00118 io_ssl->fd = fd;
00119 io_ssl->flags = flags;
00120
00121 io_ssl->ssl = SSL_new(ssl_ctx);
00122 dbg_err_if(io_ssl->ssl == NULL);
00123
00124
00125 dbg_err_if(SSL_set_fd(io_ssl->ssl, fd) == 0);
00126
00127 io_ssl->io.read = (io_read_op) io_ssl_read;
00128 io_ssl->io.write = (io_write_op) io_ssl_write;
00129 io_ssl->io.term = (io_term_op) io_ssl_term;
00130 io_ssl->io.size = 0;
00131
00132
00133 io_ssl->io.is_secure = 1;
00134
00135
00136 while((rc = SSL_accept(io_ssl->ssl)) <= 0)
00137 {
00138
00139 if(BIO_sock_should_retry(rc))
00140 continue;
00141
00142 if(SSL_get_error(io_ssl->ssl, rc) == SSL_ERROR_WANT_READ)
00143 break;
00144
00145 warn_err("SSL accept error: %d", SSL_get_error(io_ssl->ssl, rc));
00146 }
00147
00148 *pio = (io_t*)io_ssl;
00149
00150 return 0;
00151 err:
00152 if(io_ssl && io_ssl->ssl)
00153 {
00154
00155 if((vfy = SSL_get_verify_result(io_ssl->ssl)) != X509_V_OK)
00156 warn("SSL client cert verify error: %s",
00157 X509_verify_cert_error_string(vfy));
00158 SSL_set_shutdown(io_ssl->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
00159 }
00160 if(io_ssl)
00161 io_free((io_t *)io_ssl);
00162 return ~0;
00163 }