svn update: 48958 (latest:48959)
[framework/uifw/ecore.git] / src / lib / ecore_con / ecore_con_ssl.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #ifdef HAVE_CONFIG_H
6 # include <config.h>
7 #endif
8
9 #if USE_GNUTLS
10 # include <gnutls/gnutls.h>
11 #elif USE_OPENSSL
12 # include <openssl/ssl.h>
13 #endif
14
15 #ifdef HAVE_WS2TCPIP_H
16 # include <ws2tcpip.h>
17 #endif
18
19 #include "Ecore.h"
20 #include "ecore_con_private.h"
21
22 static int _init_con_ssl_init_count = 0;
23
24 #if USE_GNUTLS
25 static int _client_connected = 0;
26
27 # define SSL_SUFFIX(ssl_func) ssl_func##_gnutls
28 # define _ECORE_CON_SSL_AVAILABLE 1
29
30 #elif USE_OPENSSL
31 # define SSL_SUFFIX(ssl_func) ssl_func##_openssl
32 # define _ECORE_CON_SSL_AVAILABLE 2
33
34 #else
35 # define SSL_SUFFIX(ssl_func) ssl_func##_none
36 # define _ECORE_CON_SSL_AVAILABLE 0
37
38 #endif
39
40 static Ecore_Con_Ssl_Error
41 SSL_SUFFIX(_ecore_con_ssl_init)(void);
42 static Ecore_Con_Ssl_Error
43 SSL_SUFFIX(_ecore_con_ssl_shutdown)(void);
44
45 static void
46 SSL_SUFFIX(_ecore_con_ssl_server_prepare)(Ecore_Con_Server *svr);
47 static Ecore_Con_Ssl_Error
48 SSL_SUFFIX(_ecore_con_ssl_server_init)(Ecore_Con_Server *svr);
49 static Ecore_Con_Ssl_Error
50 SSL_SUFFIX(_ecore_con_ssl_server_shutdown)(Ecore_Con_Server *svr);
51 static Ecore_Con_State
52 SSL_SUFFIX(_ecore_con_ssl_server_try)(Ecore_Con_Server *svr);
53 static int
54 SSL_SUFFIX(_ecore_con_ssl_server_read)(Ecore_Con_Server *svr, unsigned char *buf, int size);
55 static int
56 SSL_SUFFIX(_ecore_con_ssl_server_write)(Ecore_Con_Server *svr, unsigned char *buf, int size);
57
58 static void
59 SSL_SUFFIX(_ecore_con_ssl_client_prepare)(Ecore_Con_Client *cl);
60 static Ecore_Con_Ssl_Error
61 SSL_SUFFIX(_ecore_con_ssl_client_init)(Ecore_Con_Client *cl);
62 static Ecore_Con_Ssl_Error
63 SSL_SUFFIX(_ecore_con_ssl_client_shutdown)(Ecore_Con_Client *cl);
64 static int
65 SSL_SUFFIX(_ecore_con_ssl_client_read)(Ecore_Con_Client *cl, unsigned char *buf, int size);
66 static int
67 SSL_SUFFIX(_ecore_con_ssl_client_write)(Ecore_Con_Client *cl, unsigned char *buf, int size);
68
69 /*
70  * General SSL API
71  */
72
73 Ecore_Con_Ssl_Error
74 ecore_con_ssl_init(void)
75 {
76   if (!_init_con_ssl_init_count++)
77     SSL_SUFFIX(_ecore_con_ssl_init)();
78
79   return _init_con_ssl_init_count;
80 }
81
82 Ecore_Con_Ssl_Error
83 ecore_con_ssl_shutdown(void)
84 {
85   if (!--_init_con_ssl_init_count)
86     SSL_SUFFIX(_ecore_con_ssl_shutdown)();
87
88   return _init_con_ssl_init_count;
89 }
90
91 /**
92  * Returns if SSL support is available
93  * @return  1 if SSL is available, 0 if it is not.
94  * @ingroup Ecore_Con_Client_Group
95  */
96 int
97 ecore_con_ssl_available_get(void)
98 {
99   return _ECORE_CON_SSL_AVAILABLE;
100 }
101
102
103 void
104 ecore_con_ssl_server_prepare(Ecore_Con_Server *svr)
105 {
106   SSL_SUFFIX(_ecore_con_ssl_server_prepare)(svr);
107 }
108
109 Ecore_Con_Ssl_Error
110 ecore_con_ssl_server_init(Ecore_Con_Server *svr)
111 {
112   return SSL_SUFFIX(_ecore_con_ssl_server_init)(svr);
113 }
114
115 Ecore_Con_Ssl_Error
116 ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr)
117 {
118   return SSL_SUFFIX(_ecore_con_ssl_server_shutdown)(svr);
119 }
120
121 Ecore_Con_State
122 ecore_con_ssl_server_try(Ecore_Con_Server *svr)
123 {
124   return SSL_SUFFIX(_ecore_con_ssl_server_try)(svr);
125 }
126
127 int
128 ecore_con_ssl_server_read(Ecore_Con_Server *svr, unsigned char *buf, int size)
129 {
130   return SSL_SUFFIX(_ecore_con_ssl_server_read)(svr, buf, size);
131 }
132
133 int
134 ecore_con_ssl_server_write(Ecore_Con_Server *svr, unsigned char *buf, int size)
135 {
136   return SSL_SUFFIX(_ecore_con_ssl_server_write)(svr, buf, size);
137 }
138
139 Ecore_Con_Ssl_Error
140 ecore_con_ssl_client_init(Ecore_Con_Client *cl)
141 {
142   return SSL_SUFFIX(_ecore_con_ssl_client_init)(cl);
143 }
144
145 Ecore_Con_Ssl_Error
146 ecore_con_ssl_client_shutdown(Ecore_Con_Client *cl)
147 {
148   return SSL_SUFFIX(_ecore_con_ssl_client_shutdown)(cl);
149 }
150
151 int
152 ecore_con_ssl_client_read(Ecore_Con_Client *cl, unsigned char *buf, int size)
153 {
154   return SSL_SUFFIX(_ecore_con_ssl_client_read)(cl, buf, size);
155 }
156
157 int
158 ecore_con_ssl_client_write(Ecore_Con_Client *cl, unsigned char *buf, int size)
159 {
160   return SSL_SUFFIX(_ecore_con_ssl_client_write)(cl, buf, size);
161 }
162
163 #if USE_GNUTLS
164
165 /*
166  * GnuTLS
167  */
168
169 static Ecore_Con_Ssl_Error
170 _ecore_con_ssl_init_gnutls(void)
171 {
172   if (gnutls_global_init())
173     return ECORE_CON_SSL_ERROR_INIT_FAILED;
174
175   return ECORE_CON_SSL_ERROR_NONE;
176 }
177
178 static Ecore_Con_Ssl_Error
179 _ecore_con_ssl_shutdown_gnutls(void)
180 {
181   gnutls_global_deinit();
182
183   return ECORE_CON_SSL_ERROR_NONE;
184 }
185
186 static void
187 _ecore_con_ssl_server_prepare_gnutls(Ecore_Con_Server *svr)
188 {
189   svr->session = NULL;
190   svr->anoncred_c = NULL;
191   return;
192 }
193
194 static Ecore_Con_Ssl_Error
195 _ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr)
196 {
197   const int *proto = NULL;
198   int ret;
199   const int kx[] = { GNUTLS_KX_ANON_DH, 0 };
200   const int ssl3_proto[] = { GNUTLS_SSL3, 0 };
201   const int tls_proto[] = {
202     GNUTLS_TLS1_0,
203     GNUTLS_TLS1_1,
204 #ifdef USE_GNUTLS2
205     GNUTLS_TLS1_2,
206 #endif
207     0
208   };
209
210   switch (svr->type & ECORE_CON_SSL)
211     {
212     case ECORE_CON_USE_SSL2: /* not supported because of security issues */
213       return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
214     case ECORE_CON_USE_SSL3:
215       proto = ssl3_proto;
216       break;
217     case ECORE_CON_USE_TLS:
218       proto = tls_proto;
219       break;
220     default:
221       return ECORE_CON_SSL_ERROR_NONE;
222     }
223
224   gnutls_anon_allocate_client_credentials(&(svr->anoncred_c));
225   gnutls_init(&(svr->session), GNUTLS_CLIENT);
226   gnutls_set_default_priority(svr->session);
227   gnutls_kx_set_priority(svr->session, kx);
228   gnutls_credentials_set(svr->session, GNUTLS_CRD_ANON, svr->anoncred_c);
229   gnutls_kx_set_priority(svr->session, kx);
230   gnutls_protocol_set_priority(svr->session, proto);
231   gnutls_dh_set_prime_bits(svr->session, 512);
232
233   gnutls_transport_set_ptr(svr->session, (gnutls_transport_ptr_t)svr->fd);
234
235   while ((ret = gnutls_handshake(svr->session)) < 0)
236     {
237       if ((ret == GNUTLS_E_AGAIN) ||
238           (ret == GNUTLS_E_INTERRUPTED))
239         continue;
240
241       _ecore_con_ssl_server_shutdown_gnutls(svr);
242       return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
243     }
244
245   return ECORE_CON_SSL_ERROR_NONE;
246 }
247
248 static Ecore_Con_Ssl_Error
249 _ecore_con_ssl_server_shutdown_gnutls(Ecore_Con_Server *svr)
250 {
251   if (svr->session)
252     {
253       gnutls_bye(svr->session, GNUTLS_SHUT_RDWR);
254       gnutls_deinit(svr->session);
255     }
256   if (svr->anoncred_c)
257     gnutls_anon_free_client_credentials(svr->anoncred_c);
258   _ecore_con_ssl_server_prepare_gnutls(svr);
259
260   return ECORE_CON_SSL_ERROR_NONE;
261 }
262
263 /* Tries to connect an Ecore_Con_Server to an SSL host.
264  * Returns 1 on success, -1 on fatal errors and 0 if the caller
265  * should try again later.
266  */
267 static Ecore_Con_State
268 _ecore_con_ssl_server_try_gnutls(Ecore_Con_Server *svr __UNUSED__)
269 {
270    return ECORE_CON_CONNECTED;
271 }
272
273 static int
274 _ecore_con_ssl_server_read_gnutls(Ecore_Con_Server *svr, unsigned char *buf, int size)
275 {
276   int num;
277
278   num = gnutls_record_recv(svr->session, buf, size);
279   if (num > 0)
280     return num;
281   if ((num == GNUTLS_E_AGAIN) ||
282       (num == GNUTLS_E_REHANDSHAKE) ||
283       (num == GNUTLS_E_INTERRUPTED))
284     return 0;
285   return -1;
286 }
287
288 static int
289 _ecore_con_ssl_server_write_gnutls(Ecore_Con_Server *svr, unsigned char *buf, int size)
290 {
291   int num;
292
293   num = gnutls_record_send(svr->session, buf, size);
294   if (num > 0)
295     return num;
296   if ((num == GNUTLS_E_AGAIN) ||
297       (num == GNUTLS_E_REHANDSHAKE) ||
298       (num == GNUTLS_E_INTERRUPTED))
299     return 0;
300   return -1;
301 }
302
303 static void
304 _ecore_con_ssl_client_prepare_gnutls(Ecore_Con_Client *cl)
305 {
306   cl->session = NULL;
307   if (!_client_connected)
308     cl->server->anoncred_s = NULL;
309 }
310
311 static Ecore_Con_Ssl_Error
312 _ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
313 {
314   const int *proto = NULL;
315   gnutls_dh_params_t dh_params;
316   int ret;
317   const int kx[] = { GNUTLS_KX_ANON_DH, 0 };
318   const int ssl3_proto[] = { GNUTLS_SSL3, 0 };
319   const int tls_proto[] = {
320     GNUTLS_TLS1_0,
321     GNUTLS_TLS1_1,
322 #ifdef USE_GNUTLS2
323     GNUTLS_TLS1_2,
324 #endif
325     0
326   };
327
328   switch (cl->server->type & ECORE_CON_SSL)
329     {
330     case ECORE_CON_USE_SSL2: /* not supported because of security issues */
331       return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
332     case ECORE_CON_USE_SSL3:
333       proto = ssl3_proto;
334       break;
335     case ECORE_CON_USE_TLS:
336       proto = tls_proto;
337       break;
338     default:
339       return ECORE_CON_SSL_ERROR_NONE;
340     }
341
342   _client_connected++;
343   if (!cl->server->anoncred_s)
344     {
345       gnutls_anon_allocate_server_credentials(&(cl->server->anoncred_s));
346       gnutls_dh_params_init(&dh_params);
347       gnutls_dh_params_generate2(dh_params, 512);
348       gnutls_anon_set_server_dh_params(cl->server->anoncred_s, dh_params);
349     }
350
351   gnutls_init(&(cl->session), GNUTLS_SERVER);
352   gnutls_set_default_priority(cl->session);
353   gnutls_credentials_set(cl->session, GNUTLS_CRD_ANON, cl->server->anoncred_s);
354
355   gnutls_kx_set_priority(cl->session, kx);
356
357   gnutls_protocol_set_priority(cl->session, proto);
358
359   gnutls_dh_set_prime_bits(cl->session, 512);
360
361   gnutls_transport_set_ptr(cl->session, (gnutls_transport_ptr_t)cl->fd);
362
363   while ((ret = gnutls_handshake(cl->session)) < 0)
364     {
365       if ((ret == GNUTLS_E_AGAIN) ||
366           (ret == GNUTLS_E_INTERRUPTED))
367         continue;
368
369       _ecore_con_ssl_client_shutdown_gnutls(cl);
370       return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
371     }
372
373   return ECORE_CON_SSL_ERROR_NONE;
374 }
375
376 static Ecore_Con_Ssl_Error
377 _ecore_con_ssl_client_shutdown_gnutls(Ecore_Con_Client *cl)
378 {
379   if (cl->session)
380     {
381       gnutls_bye(cl->session, GNUTLS_SHUT_RDWR);
382       gnutls_deinit(cl->session);
383     }
384   if (cl->server->anoncred_s && !--_client_connected)
385     gnutls_anon_free_server_credentials(cl->server->anoncred_s);
386   _ecore_con_ssl_client_prepare_gnutls(cl);
387
388   return ECORE_CON_SSL_ERROR_NONE;
389 }
390
391 static int
392 _ecore_con_ssl_client_read_gnutls(Ecore_Con_Client *cl, unsigned char *buf, int size)
393 {
394   int num;
395
396   num = gnutls_record_recv(cl->session, buf, size);
397   if (num > 0)
398     return num;
399   if ((num == GNUTLS_E_AGAIN) ||
400       (num == GNUTLS_E_REHANDSHAKE) ||
401       (num == GNUTLS_E_INTERRUPTED))
402     return 0;
403   return -1;
404 }
405
406 static int
407 _ecore_con_ssl_client_write_gnutls(Ecore_Con_Client *cl, unsigned char *buf, int size)
408 {
409   int num;
410
411   num = gnutls_record_send(cl->session, buf, size);
412   if (num > 0)
413     return num;
414   if ((num == GNUTLS_E_AGAIN) ||
415       (num == GNUTLS_E_REHANDSHAKE) ||
416       (num == GNUTLS_E_INTERRUPTED))
417     return 0;
418   return -1;
419 }
420
421 #elif USE_OPENSSL
422
423 /*
424  * OpenSSL
425  */
426
427 static Ecore_Con_Ssl_Error
428 _ecore_con_ssl_init_openssl(void)
429 {
430   SSL_library_init();
431   SSL_load_error_strings();
432
433   return ECORE_CON_SSL_ERROR_NONE;
434 }
435
436 static Ecore_Con_Ssl_Error
437 _ecore_con_ssl_shutdown_openssl(void)
438 {
439   // FIXME nothing to do ?
440   return ECORE_CON_SSL_ERROR_NONE;
441 }
442
443 static void
444 _ecore_con_ssl_server_prepare_openssl(Ecore_Con_Server *svr)
445 {
446   svr->ssl = NULL;
447   svr->ssl_ctx = NULL;
448   svr->ssl_err = SSL_ERROR_NONE;
449 }
450
451 static Ecore_Con_Ssl_Error
452 _ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr)
453 {
454   switch (svr->type & ECORE_CON_SSL)
455     {
456     case ECORE_CON_USE_SSL2:
457       /* Unsafe version of SSL */
458       if (!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
459         return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
460       break;
461     case ECORE_CON_USE_SSL3:
462       if (!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())))
463         return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
464       break;
465     case ECORE_CON_USE_TLS:
466       if (!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())))
467         return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
468       break;
469     default:
470       return ECORE_CON_SSL_ERROR_NONE;
471     }
472   if (!(svr->ssl = SSL_new(svr->ssl_ctx)))
473     {
474       SSL_CTX_free(svr->ssl_ctx);
475       return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
476     }
477
478   SSL_set_fd(svr->ssl, svr->fd);
479
480   return ECORE_CON_SSL_ERROR_NONE;
481 }
482
483 static Ecore_Con_Ssl_Error
484 _ecore_con_ssl_server_shutdown_openssl(Ecore_Con_Server *svr)
485 {
486   if (svr->ssl)
487     {
488       if (!SSL_shutdown(svr->ssl))
489         SSL_shutdown(svr->ssl);
490       SSL_free(svr->ssl);
491     }
492   if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx);
493
494   _ecore_con_ssl_server_prepare_openssl(svr);
495
496   return ECORE_CON_SSL_ERROR_NONE;
497 }
498
499 /* Tries to connect an Ecore_Con_Server to an SSL host.
500  * Returns 1 on success, -1 on fatal errors and 0 if the caller
501  * should try again later.
502  */
503 static Ecore_Con_State
504 _ecore_con_ssl_server_try_openssl(Ecore_Con_Server *svr)
505 {
506    int res, flag = 0;
507
508    if ((res = SSL_connect(svr->ssl)) == 1)
509      return ECORE_CON_CONNECTED;
510
511    svr->ssl_err = SSL_get_error(svr->ssl, res);
512
513    switch (svr->ssl_err)
514      {
515      case SSL_ERROR_NONE:
516        return ECORE_CON_CONNECTED;
517      case SSL_ERROR_WANT_READ:
518        flag = ECORE_FD_READ;
519        break;
520      case SSL_ERROR_WANT_WRITE:
521        flag = ECORE_FD_WRITE;
522        break;
523      default:
524        return ECORE_CON_DISCONNECTED;
525      }
526
527    if (svr->fd_handler && flag)
528      ecore_main_fd_handler_active_set(svr->fd_handler, flag);
529
530    return ECORE_CON_INPROGRESS;
531 }
532
533 static int
534 _ecore_con_ssl_server_read_openssl(Ecore_Con_Server *svr, unsigned char *buf, int size)
535 {
536   int num;
537
538   num = SSL_read(svr->ssl, buf, size);
539   svr->ssl_err = SSL_get_error(svr->ssl, num);
540
541   if (svr->fd_handler)
542     {
543       if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ)
544         ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
545       else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE)
546         ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
547     }
548
549   if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
550       (svr->ssl_err == SSL_ERROR_SYSCALL) ||
551       (svr->ssl_err == SSL_ERROR_SSL))
552     return -1;
553   if (num < 0)
554     return 0;
555   return num;
556 }
557
558 static int
559 _ecore_con_ssl_server_write_openssl(Ecore_Con_Server *svr, unsigned char *buf, int size)
560 {
561   int num;
562
563   num = SSL_write(svr->ssl, buf, size);
564   svr->ssl_err = SSL_get_error(svr->ssl, num);
565
566   if (svr->fd_handler)
567     {
568       if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ)
569         ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
570       else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE)
571         ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
572     }
573
574   if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
575       (svr->ssl_err == SSL_ERROR_SYSCALL) ||
576       (svr->ssl_err == SSL_ERROR_SSL))
577     return -1;
578   if (num < 0)
579     return 0;
580   return num;
581 }
582
583 static void
584 _ecore_con_ssl_client_prepare_openssl(Ecore_Con_Client *cl)
585 {
586   cl->ssl = NULL;
587   cl->ssl_ctx = NULL;
588   cl->ssl_err = SSL_ERROR_NONE;
589 }
590
591 static Ecore_Con_Ssl_Error
592 _ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl)
593 {
594     switch (cl->server->type & ECORE_CON_SSL)
595     {
596     case ECORE_CON_USE_SSL2:
597       /* Unsafe version of SSL */
598       if (!(cl->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
599         return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
600       break;
601     case ECORE_CON_USE_SSL3:
602       if (!(cl->ssl_ctx = SSL_CTX_new(SSLv3_client_method())))
603         return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
604       break;
605     case ECORE_CON_USE_TLS:
606       if (!(cl->ssl_ctx = SSL_CTX_new(TLSv1_client_method())))
607         return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
608       break;
609     default:
610       return ECORE_CON_SSL_ERROR_NONE;
611     }
612   if (!(cl->ssl = SSL_new(cl->ssl_ctx)))
613     {
614       SSL_CTX_free(cl->ssl_ctx);
615       return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
616     }
617
618   SSL_set_fd(cl->ssl, cl->fd);
619
620   return ECORE_CON_SSL_ERROR_NONE;
621 }
622
623 static Ecore_Con_Ssl_Error
624 _ecore_con_ssl_client_shutdown_openssl(Ecore_Con_Client *cl)
625 {
626   if (cl->ssl)
627     {
628       if (!SSL_shutdown(cl->ssl))
629         SSL_shutdown(cl->ssl);
630       SSL_free(cl->ssl);
631     }
632   if (cl->ssl_ctx) SSL_CTX_free(cl->ssl_ctx);
633
634   _ecore_con_ssl_client_prepare_openssl(cl);
635
636   return ECORE_CON_SSL_ERROR_NONE;
637 }
638
639 static int
640 _ecore_con_ssl_client_read_openssl(Ecore_Con_Client *cl, unsigned char *buf, int size)
641 {
642   int num;
643
644   num = SSL_read(cl->ssl, buf, size);
645   cl->ssl_err = SSL_get_error(cl->ssl, num);
646
647   if (cl->fd_handler)
648     {
649       if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ)
650         ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
651       else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE)
652         ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
653     }
654
655   if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
656       (cl->ssl_err == SSL_ERROR_SYSCALL) ||
657       (cl->ssl_err == SSL_ERROR_SSL))
658     return -1;
659   if (num < 0)
660     return 0;
661   return num;
662 }
663
664 static int
665 _ecore_con_ssl_client_write_openssl(Ecore_Con_Client *cl, unsigned char *buf, int size)
666 {
667   int num;
668
669   num = SSL_write(cl->ssl, buf, size);
670   cl->ssl_err = SSL_get_error(cl->ssl, num);
671
672   if (cl->fd_handler)
673     {
674       if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ)
675         ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
676       else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE)
677         ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
678     }
679
680   if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
681       (cl->ssl_err == SSL_ERROR_SYSCALL) ||
682       (cl->ssl_err == SSL_ERROR_SSL))
683     return -1;
684   if (num < 0)
685     return 0;
686   return num;
687 }
688
689 #else
690
691 /*
692  * No Ssl
693  */
694
695 static Ecore_Con_Ssl_Error
696 _ecore_con_ssl_init_none(void)
697 {
698   return ECORE_CON_SSL_ERROR_NONE;
699 }
700
701 static Ecore_Con_Ssl_Error
702 _ecore_con_ssl_shutdown_none(void)
703 {
704   return ECORE_CON_SSL_ERROR_NONE;
705 }
706
707 static void
708 _ecore_con_ssl_server_prepare_none(Ecore_Con_Server *svr)
709 {
710 }
711
712 static Ecore_Con_Ssl_Error
713 _ecore_con_ssl_server_init_none(Ecore_Con_Server *svr)
714 {
715   return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
716 }
717
718 static Ecore_Con_Ssl_Error
719 _ecore_con_ssl_server_shutdown_none(Ecore_Con_Server *svr)
720 {
721   return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
722 }
723
724 /* Tries to connect an Ecore_Con_Server to an SSL host.
725  * Returns 1 on success, -1 on fatal errors and 0 if the caller
726  * should try again later.
727  */
728 static Ecore_Con_State
729 _ecore_con_ssl_server_try_none(Ecore_Con_Server *svr)
730 {
731   return ECORE_CON_DISCONNECTED;
732 }
733
734 static int
735 _ecore_con_ssl_server_read_none(Ecore_Con_Server *svr, unsigned char *buf, int size)
736 {
737   return -1;
738 }
739
740 static int
741 _ecore_con_ssl_server_write_none(Ecore_Con_Server *svr, unsigned char *buf, int size)
742 {
743   return -1;
744 }
745
746 static void
747 _ecore_con_ssl_client_prepare_none(Ecore_Con_Client *cl)
748 {
749   return;
750 }
751
752 static Ecore_Con_Ssl_Error
753 _ecore_con_ssl_client_init_none(Ecore_Con_Client *cl)
754 {
755   return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
756 }
757
758 static Ecore_Con_Ssl_Error
759 _ecore_con_ssl_client_shutdown_none(Ecore_Con_Client *cl)
760 {
761   return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
762 }
763
764 static int
765 _ecore_con_ssl_client_read_none(Ecore_Con_Client *cl, unsigned char *buf, int size)
766 {
767   return -1;
768 }
769
770 static int
771 _ecore_con_ssl_client_write_none(Ecore_Con_Client *cl, unsigned char *buf, int size)
772 {
773   return -1;
774 }
775
776 #endif