[IOMultiplexerV2] added more socket examples
[NextIRCd.git] / src / IOHandler / IOSSLBackend.c
1 /* IOSSLBackend.c - IOMultiplexer
2  * Copyright (C) 2014  Philipp Kreil (pk910)
3  * 
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License 
15  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
16  */
17 #define _IOHandler_internals
18 #include "IOInternal.h"
19 #include "IOHandler.h"
20 #include "IOLog.h"
21 #include "IOSockets.h"
22 #include "IOSSLBackend.h"
23
24 #if defined(HAVE_GNUTLS_GNUTLS_H)
25 #include <string.h>
26 #include <stdlib.h>
27 #include <errno.h>
28 /* GnuTLS Backend */
29 static gnutls_dh_params_t dh_params;
30
31 static int generate_dh_params() {
32         unsigned int bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY);
33         gnutls_dh_params_init(&dh_params);
34         gnutls_dh_params_generate2(dh_params, bits);
35         return 0;
36 }
37
38 void iossl_init() {
39     int ret;
40         if((ret = gnutls_global_init()) != GNUTLS_E_SUCCESS) {
41                 iolog_trigger(IOLOG_ERROR, "SSL: gnutls_global_init(): failed (%d)", ret);
42                 //TODO: Error handling?
43                 return;
44         }
45         generate_dh_params();
46 }
47
48 // Client
49 void iossl_connect(struct _IOSocket *iosock) {
50     struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
51         int err;
52         
53         err = gnutls_certificate_allocate_credentials(&sslnode->ssl.client.credentials);
54         if(err < 0) {
55                 goto ssl_connect_err;
56         }
57         
58         gnutls_init(&sslnode->ssl.client.session, GNUTLS_CLIENT);
59         
60         gnutls_priority_set_direct(sslnode->ssl.client.session, "NONE:+VERS-TLS1.0:+VERS-SSL3.0:+CIPHER-ALL:+COMP-ALL:+RSA:+DHE-RSA:+DHE-DSS:+MAC-ALL", NULL);
61         gnutls_credentials_set(sslnode->ssl.client.session, GNUTLS_CRD_CERTIFICATE, sslnode->ssl.client.credentials);
62     
63         gnutls_transport_set_int(sslnode->ssl.client.session, iosock->fd);
64         gnutls_handshake_set_timeout(sslnode->ssl.client.session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
65         
66     iosock->sslnode = sslnode;
67         iosock->socket_flags |= IOSOCKETFLAG_SSL_HANDSHAKE;
68     iossl_client_handshake(iosock);
69     return;
70 ssl_connect_err:
71     free(sslnode);
72     iosocket_events_callback(iosock, 0, 0);
73 }
74
75 void iossl_client_handshake(struct _IOSocket *iosock) {
76     // Perform an SSL handshake.
77     int ret = gnutls_handshake(iosock->sslnode->ssl.client.session);
78     iosock->socket_flags &= ~IOSOCKETFLAG_SSL_WANTWRITE;
79         
80         if(ret < 0) {
81                 if(gnutls_error_is_fatal(ret) == 0) {
82                         if(gnutls_record_get_direction(iosock->sslnode->ssl.client.session)) {
83                                 iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE;
84                                 iolog_trigger(IOLOG_DEBUG, "gnutls_handshake for fd %d wants to write...", iosock->fd);
85                         } else {
86                                 iolog_trigger(IOLOG_DEBUG, "gnutls_handshake for fd %d wants to read...", iosock->fd);
87                         }
88                 } else {
89                         iolog_trigger(IOLOG_ERROR, "gnutls_handshake for fd %d failed with %s", iosock->fd, gnutls_strerror(ret));
90                         iosocket_events_callback(iosock, 0, 0);
91                 }
92         } else {
93                 char *desc;
94                 desc = gnutls_session_get_desc(iosock->sslnode->ssl.client.session);
95                 iolog_trigger(IOLOG_DEBUG, "SSL handshake for fd %d successful: %s", iosock->fd, desc);
96                 gnutls_free(desc);
97                 iosock->socket_flags |= IOSOCKETFLAG_SSL_ESTABLISHED;
98                 iosocket_events_callback(iosock, 0, 0); //perform IOEVENT_CONNECTED event
99         }
100 }
101
102
103 // Server
104 void iossl_listen(struct _IOSocket *iosock, const char *certfile, const char *keyfile) {
105     struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
106         
107         gnutls_priority_init(&sslnode->ssl.server.priority, "NONE:+VERS-TLS1.0:+VERS-SSL3.0:+CIPHER-ALL:+COMP-ALL:+RSA:+DHE-RSA:+DHE-DSS:+MAC-ALL", NULL);
108         
109         gnutls_certificate_allocate_credentials(&sslnode->ssl.server.credentials);
110         int ret = gnutls_certificate_set_x509_key_file(sslnode->ssl.server.credentials, certfile, keyfile, GNUTLS_X509_FMT_PEM);
111     if (ret < 0) {
112                 iolog_trigger(IOLOG_ERROR, "SSL: could not load server certificate/key (%s %s): %d - %s", certfile, keyfile, ret, gnutls_strerror(ret));
113                 goto ssl_listen_err;
114         }
115         
116         gnutls_certificate_set_dh_params(sslnode->ssl.server.credentials, dh_params);
117         
118     iosock->sslnode = sslnode;
119     iosock->socket_flags |= IOSOCKETFLAG_SSL_ESTABLISHED;
120     return;
121 ssl_listen_err:
122     free(sslnode);
123     iosock->sslnode = NULL;
124     iosocket_events_callback(iosock, 0, 0);
125 }
126
127 void iossl_client_accepted(struct _IOSocket *iosock, struct _IOSocket *new_iosock) {
128     struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
129     
130         gnutls_init(&sslnode->ssl.client.session, GNUTLS_SERVER);
131         gnutls_priority_set(sslnode->ssl.client.session, iosock->sslnode->ssl.server.priority);
132         gnutls_credentials_set(sslnode->ssl.client.session, GNUTLS_CRD_CERTIFICATE, iosock->sslnode->ssl.server.credentials);
133         
134         /* We don't request any certificate from the client.
135          * If we did we would need to verify it.
136          */
137         gnutls_certificate_server_set_request(sslnode->ssl.client.session, GNUTLS_CERT_IGNORE);
138         
139         gnutls_transport_set_int(sslnode->ssl.client.session, new_iosock->fd);
140         
141     new_iosock->sslnode = sslnode;
142     new_iosock->socket_flags |= IOSOCKETFLAG_SSL_HANDSHAKE;
143     return;
144         /*
145 ssl_accept_err:
146     free(sslnode);
147     iosock->sslnode = NULL;
148     iosocket_events_callback(new_iosock, 0, 0);
149         */
150 }
151
152 void iossl_server_handshake(struct _IOSocket *iosock) {
153     return iossl_client_handshake(iosock);
154 }
155
156 void iossl_disconnect(struct _IOSocket *iosock) {
157     if(!iosock->sslnode) return;
158         
159         if((iosock->socket_flags & IOSOCKETFLAG_LISTENING)) {
160                 gnutls_certificate_free_credentials(iosock->sslnode->ssl.server.credentials);
161                 gnutls_priority_deinit(iosock->sslnode->ssl.server.priority);
162         } else {
163                 gnutls_bye(iosock->sslnode->ssl.client.session, GNUTLS_SHUT_RDWR);
164                 gnutls_certificate_free_credentials(iosock->sslnode->ssl.client.credentials);
165                 gnutls_deinit(iosock->sslnode->ssl.client.session);
166         }
167         
168     free(iosock->sslnode);
169     iosock->sslnode = NULL;
170     iosock->socket_flags &= ~IOSOCKETFLAG_SSLSOCKET;
171 }
172
173 static void iossl_rehandshake(struct _IOSocket *iosock, int hsflag) {
174         int ret = gnutls_handshake(iosock->sslnode->ssl.client.session);
175     iosock->socket_flags &= ~IOSOCKETFLAG_SSL_WANTWRITE;
176         
177         if(ret < 0) {
178                 if(gnutls_error_is_fatal(ret) == 0) {
179                         if(gnutls_record_get_direction(iosock->sslnode->ssl.client.session)) {
180                                 iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE | hsflag;
181                                 iolog_trigger(IOLOG_DEBUG, "gnutls_handshake for fd %d wants to write...", iosock->fd);
182                         } else {
183                                 iosock->socket_flags |= hsflag;
184                                 iolog_trigger(IOLOG_DEBUG, "gnutls_handshake for fd %d wants to read...", iosock->fd);
185                         }
186                 } else {
187                         iolog_trigger(IOLOG_ERROR, "gnutls_handshake for fd %d failed: %s", iosock->fd, gnutls_strerror(ret));
188                         //TODO: Error Action?
189                 }
190         } else {
191                 char *desc;
192                 desc = gnutls_session_get_desc(iosock->sslnode->ssl.client.session);
193                 iolog_trigger(IOLOG_DEBUG, "SSL handshake for fd %d successful: %s", iosock->fd, desc);
194                 gnutls_free(desc);
195                 iosock->socket_flags &= ~hsflag;
196         }
197 }
198
199 int iossl_read(struct _IOSocket *iosock, char *buffer, int len) {
200     if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED)) != (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED))
201                 return 0;
202         if((iosock->socket_flags & IOSOCKETFLAG_SSL_READHS)) {
203                 iossl_rehandshake(iosock, IOSOCKETFLAG_SSL_READHS);
204                 errno = EAGAIN;
205                 return -1;
206         }
207     int ret = gnutls_record_recv(iosock->sslnode->ssl.client.session, buffer, len);
208         if(ret == 0) {
209                 //TLS session closed
210                 //TODO: Action?
211         } else if(ret < 0 && gnutls_error_is_fatal(ret) == 0) {
212                 iolog_trigger(IOLOG_WARNING, "gnutls_record_recv for fd %d returned %s", iosock->fd, gnutls_strerror(ret));
213                 if(ret == GNUTLS_E_REHANDSHAKE) {
214                         iossl_rehandshake(iosock, IOSOCKETFLAG_SSL_READHS);
215                         errno = EAGAIN;
216                         return -1;
217                 }
218         } else if(ret < 0) {
219                 iolog_trigger(IOLOG_ERROR, "gnutls_record_recv for fd %d failed: %s", iosock->fd, gnutls_strerror(ret));
220                 errno = ret;
221                 return ret;
222         }
223     return ret;
224 }
225
226 int iossl_write(struct _IOSocket *iosock, char *buffer, int len) {
227     if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED)) != (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED))
228                 return 0;
229         if((iosock->socket_flags & IOSOCKETFLAG_SSL_WRITEHS)) {
230                 iossl_rehandshake(iosock, IOSOCKETFLAG_SSL_WRITEHS);
231                 errno = EAGAIN;
232                 return -1;
233         }
234     int ret = gnutls_record_send(iosock->sslnode->ssl.client.session, buffer, len);
235     if(ret < 0 && gnutls_error_is_fatal(ret) == 0) {
236                 iolog_trigger(IOLOG_WARNING, "gnutls_record_send for fd %d returned %s", iosock->fd, gnutls_strerror(ret));
237                 if(ret == GNUTLS_E_REHANDSHAKE) {
238                         iossl_rehandshake(iosock, IOSOCKETFLAG_SSL_WRITEHS);
239                         errno = EAGAIN;
240                         return -1;
241                 }
242         } else if(ret < 0) {
243                 iolog_trigger(IOLOG_ERROR, "gnutls_record_send for fd %d failed: %s", iosock->fd, gnutls_strerror(ret));
244                 errno = ret;
245                 return ret;
246         }
247     return ret;
248 }
249
250 #elif defined(HAVE_OPENSSL_SSL_H)
251 /* OpenSSL Backend */
252
253
254 void iossl_init() {
255     SSL_library_init();
256     OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */
257     SSL_load_error_strings();
258 }
259
260 static void iossl_error() {
261     unsigned long e;
262     while((e = ERR_get_error())) {
263         iolog_trigger(IOLOG_ERROR, "SSLv23 ERROR %lu: %s", e, ERR_error_string(e, NULL));
264     }
265 }
266
267 // Client
268 void iossl_connect(struct _IOSocket *iosock) {
269     struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
270     sslnode->sslContext = SSL_CTX_new(SSLv23_client_method());
271     if(!sslnode->sslContext) {
272         iossl_error();
273         iolog_trigger(IOLOG_ERROR, "SSL: could not create client SSL CTX");
274         goto ssl_connect_err;
275     }
276     sslnode->sslHandle = SSL_new(sslnode->sslContext);
277     if(!sslnode->sslHandle) {
278         iossl_error();
279         iolog_trigger(IOLOG_ERROR, "SSL: could not create client SSL Handle");
280         goto ssl_connect_err;
281     }
282     if(!SSL_set_fd(sslnode->sslHandle, iosock->fd)) {
283         iossl_error();
284         iolog_trigger(IOLOG_ERROR, "SSL: could not set client fd in SSL Handle");
285         goto ssl_connect_err;
286     }
287     SSL_set_connect_state(sslnode->sslHandle);
288     iosock->sslnode = sslnode;
289         iosock->socket_flags |= IOSOCKETFLAG_SSL_HANDSHAKE;
290     iossl_client_handshake(iosock);
291     return;
292 ssl_connect_err:
293     free(sslnode);
294     iosocket_events_callback(iosock, 0, 0);
295 }
296
297 void iossl_client_handshake(struct _IOSocket *iosock) {
298     // Perform an SSL handshake.
299     int ret = SSL_do_handshake(iosock->sslnode->sslHandle);
300     iosock->socket_flags &= ~IOSOCKETFLAG_SSL_WANTWRITE;
301     switch(SSL_get_error(iosock->sslnode->sslHandle, ret)) {
302         case SSL_ERROR_NONE:
303             iolog_trigger(IOLOG_DEBUG, "SSL handshake for fd %d successful", iosock->fd);
304                         iosock->socket_flags |= IOSOCKETFLAG_SSL_ESTABLISHED;
305             iosocket_events_callback(iosock, 0, 0); //perform IOEVENT_CONNECTED event
306             break;
307         case SSL_ERROR_WANT_READ:
308             iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
309             break;
310         case SSL_ERROR_WANT_WRITE:
311             iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE;
312             iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
313             break;
314         default:
315             iolog_trigger(IOLOG_ERROR, "SSL_do_handshake for fd %d failed with ", iosock->fd);
316             iosocket_events_callback(iosock, 0, 0);
317             break;
318     }
319 }
320
321
322 // Server
323 void iossl_listen(struct _IOSocket *iosock, const char *certfile, const char *keyfile) {
324     struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
325     sslnode->sslContext = SSL_CTX_new(SSLv23_server_method());
326     if(!sslnode->sslContext) {
327         iossl_error();
328         iolog_trigger(IOLOG_ERROR, "SSL: could not create server SSL CTX");
329         goto ssl_listen_err;
330     }
331     /* load certificate */
332     if(SSL_CTX_use_certificate_file(sslnode->sslContext, certfile, SSL_FILETYPE_PEM) <= 0) {
333         iossl_error();
334         iolog_trigger(IOLOG_ERROR, "SSL: could not load server certificate (%s)", certfile);
335         goto ssl_listen_err;
336     }
337     /* load keyfile */
338     if(SSL_CTX_use_PrivateKey_file(sslnode->sslContext, keyfile, SSL_FILETYPE_PEM) <= 0) {
339         iossl_error();
340         iolog_trigger(IOLOG_ERROR, "SSL: could not load server keyfile (%s)", keyfile);
341         goto ssl_listen_err;
342     }
343     /* check certificate and keyfile */
344     if(!SSL_CTX_check_private_key(sslnode->sslContext)) {
345         iossl_error();
346         iolog_trigger(IOLOG_ERROR, "SSL: server certificate (%s) and keyfile (%s) doesn't match!", certfile, keyfile);
347         goto ssl_listen_err;
348     }
349     iosock->sslnode = sslnode;\r
350     iosock->socket_flags |= IOSOCKETFLAG_SSL_ESTABLISHED;
351     return;
352 ssl_listen_err:
353     free(sslnode);
354     iosock->sslnode = NULL;
355     iosocket_events_callback(iosock, 0, 0);
356 }
357
358 void iossl_client_accepted(struct _IOSocket *iosock, struct _IOSocket *new_iosock) {
359     struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
360     sslnode->sslHandle = SSL_new(iosock->sslnode->sslContext);
361     if(!sslnode->sslHandle) {
362         iossl_error();
363         iolog_trigger(IOLOG_ERROR, "SSL: could not create client SSL Handle");
364         goto ssl_accept_err;
365     }
366     if(!SSL_set_fd(sslnode->sslHandle, new_iosock->fd)) {
367         iossl_error();
368         iolog_trigger(IOLOG_ERROR, "SSL: could not set client fd in SSL Handle");
369         goto ssl_accept_err;
370     }
371     new_iosock->sslnode = sslnode;\r
372     new_iosock->socket_flags |= IOSOCKETFLAG_SSL_HANDSHAKE;
373     return;
374 ssl_accept_err:
375     free(sslnode);\r
376     iosock->sslnode = NULL;\r
377     iosocket_events_callback(new_iosock, 0, 0);
378 }
379
380 void iossl_server_handshake(struct _IOSocket *iosock) {
381     // Perform an SSL handshake.
382     int ret = SSL_accept(iosock->sslnode->sslHandle);
383     iosock->socket_flags &= ~IOSOCKETFLAG_SSL_WANTWRITE;
384     switch(SSL_get_error(iosock->sslnode->sslHandle, ret)) {
385         case SSL_ERROR_NONE:
386             iolog_trigger(IOLOG_DEBUG, "SSL handshake for fd %d successful", iosock->fd);
387                         iosock->socket_flags |= IOSOCKETFLAG_SSL_ESTABLISHED;
388             iosocket_events_callback(iosock, 0, 0); //perform IOEVENT_CONNECTED event
389             break;
390         case SSL_ERROR_WANT_READ:
391             iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
392             break;
393         case SSL_ERROR_WANT_WRITE:
394             iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE;
395             iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
396             break;
397         default:
398             iolog_trigger(IOLOG_ERROR, "SSL_do_handshake for fd %d failed with ", iosock->fd);
399             iosocket_events_callback(iosock, 0, 0);
400             break;
401     }
402 }
403
404 void iossl_disconnect(struct _IOSocket *iosock) {
405     if(!iosock->sslnode) return;
406     SSL_shutdown(iosock->sslnode->sslHandle);
407     SSL_free(iosock->sslnode->sslHandle);
408     SSL_CTX_free(iosock->sslnode->sslContext);
409     free(iosock->sslnode);
410     iosock->sslnode = NULL;
411     iosock->socket_flags &= ~IOSOCKETFLAG_SSLSOCKET;
412 }
413
414 int iossl_read(struct _IOSocket *iosock, char *buffer, int len) {
415     if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED)) != (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED))\r
416                 return 0;
417     int ret = SSL_read(iosock->sslnode->sslHandle, buffer, len);
418     iosock->socket_flags &= ~(IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_READHS);
419     switch(SSL_get_error(iosock->sslnode->sslHandle, ret)) {
420         case SSL_ERROR_NONE:
421         case SSL_ERROR_ZERO_RETURN:
422             break;
423         case SSL_ERROR_WANT_READ:\r
424                         iosock->socket_flags |= IOSOCKETFLAG_SSL_READHS;
425             iolog_trigger(IOLOG_DEBUG, "SSL_read for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
426             errno = EAGAIN;
427             ret = -1;
428             break;
429         case SSL_ERROR_WANT_WRITE:
430             iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_READHS;
431             iolog_trigger(IOLOG_DEBUG, "SSL_read for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
432             errno = EAGAIN;
433             ret = -1;
434             break;
435         default:
436             iolog_trigger(IOLOG_ERROR, "SSL_read for fd %d failed with ", iosock->fd);
437             ret = -1;
438             break;
439     }\r
440     return ret;
441 }
442
443 int iossl_write(struct _IOSocket *iosock, char *buffer, int len) {
444     if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED)) != (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED))\r
445                 return 0;
446     int ret = SSL_write(iosock->sslnode->sslHandle, buffer, len);
447     iosock->socket_flags &= ~(IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_WRITEHS);
448     switch(SSL_get_error(iosock->sslnode->sslHandle, ret)) {
449         case SSL_ERROR_NONE:
450         case SSL_ERROR_ZERO_RETURN:
451             break;
452         case SSL_ERROR_WANT_READ:
453             iosock->socket_flags |= IOSOCKETFLAG_SSL_WRITEHS;
454             iolog_trigger(IOLOG_DEBUG, "SSL_write for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
455             errno = EAGAIN;
456             ret = -1;
457             break;
458         case SSL_ERROR_WANT_WRITE:
459             iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_WRITEHS;
460             iolog_trigger(IOLOG_DEBUG, "SSL_write for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
461             errno = EAGAIN;
462             ret = -1;
463             break;
464         default:
465             iolog_trigger(IOLOG_ERROR, "SSL_write for fd %d failed with ", iosock->fd);
466             ret = -1;
467             break;
468     }\r
469     return ret;
470 }
471
472 #else
473 // NULL-backend
474
475 void iossl_init() {};
476 void iossl_connect(struct _IOSocket *iosock) {};
477 void iossl_listen(struct _IOSocket *iosock, const char *certfile, const char *keyfile) {};
478 void iossl_client_handshake(struct _IOSocket *iosock) {};
479 void iossl_client_accepted(struct _IOSocket *iosock, struct _IOSocket *client_iofd) {};
480 void iossl_server_handshake(struct _IOSocket *iosock) {};
481 void iossl_disconnect(struct _IOSocket *iosock) {};
482 int iossl_read(struct _IOSocket *iosock, char *buffer, int len) { return 0; };
483 int iossl_write(struct _IOSocket *iosock, char *buffer, int len) { return 0; };
484 #endif