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 static int io_ssl_connect(io_ssl_t *io_ssl)
00124 {
00125 int rc;
00126
00127
00128 while((rc = SSL_connect(io_ssl->ssl)) <= 0)
00129 {
00130
00131 if(BIO_sock_should_retry(rc))
00132 continue;
00133
00134 if(SSL_get_error(io_ssl->ssl, rc) == SSL_ERROR_WANT_READ)
00135 break;
00136
00137 warn_err("SSL accept error: %d", SSL_get_error(io_ssl->ssl, rc));
00138 }
00139
00140 return 0;
00141 err:
00142 return ~0;
00143 }
00144
00145 static int io_ssl_accept(io_ssl_t *io_ssl)
00146 {
00147 int rc;
00148
00149
00150 while((rc = SSL_accept(io_ssl->ssl)) <= 0)
00151 {
00152
00153 if(BIO_sock_should_retry(rc))
00154 continue;
00155
00156 if(SSL_get_error(io_ssl->ssl, rc) == SSL_ERROR_WANT_READ)
00157 break;
00158
00159 warn_err("SSL accept error: %d", SSL_get_error(io_ssl->ssl, rc));
00160 }
00161
00162 return 0;
00163 err:
00164 return ~0;
00165 }
00166
00167 int io_ssl_create(int fd, int flags, int client_mode,
00168 SSL_CTX *ssl_ctx, io_t **pio)
00169 {
00170 io_ssl_t *io_ssl = NULL;
00171 int rc = 0;
00172 long vfy;
00173
00174 dbg_return_if (pio == NULL, ~0);
00175 dbg_return_if (ssl_ctx == NULL, ~0);
00176
00177 dbg_err_if(io_create(io_ssl_t, (io_t**)&io_ssl));
00178
00179 io_ssl->io.type = IO_TYPE_SSL;
00180
00181 io_ssl->fd = fd;
00182 io_ssl->flags = flags;
00183
00184 io_ssl->ssl = SSL_new(ssl_ctx);
00185 dbg_err_if(io_ssl->ssl == NULL);
00186
00187
00188 dbg_err_if(SSL_set_fd(io_ssl->ssl, fd) == 0);
00189
00190 io_ssl->io.read = (io_read_op) io_ssl_read;
00191 io_ssl->io.write = (io_write_op) io_ssl_write;
00192 io_ssl->io.close = (io_close_op) io_ssl_close;
00193 io_ssl->io.free = (io_free_op) io_ssl_free;
00194 io_ssl->io.size = 0;
00195
00196
00197 io_ssl->io.is_secure = 1;
00198
00199
00200 if(client_mode)
00201 dbg_err_if(io_ssl_connect(io_ssl));
00202 else
00203 dbg_err_if(io_ssl_accept(io_ssl));
00204
00205 *pio = (io_t*)io_ssl;
00206
00207 return 0;
00208 err:
00209 if(io_ssl && io_ssl->ssl)
00210 {
00211
00212 if((vfy = SSL_get_verify_result(io_ssl->ssl)) != X509_V_OK)
00213 warn("SSL client cert verify error: %s",
00214 X509_verify_cert_error_string(vfy));
00215 SSL_set_shutdown(io_ssl->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
00216 }
00217 if(io_ssl)
00218 io_free((io_t *)io_ssl);
00219 return ~0;
00220 }
00221