allow certificates to be loaded for STARTTLS
[framework/uifw/ecore.git] / src / lib / ecore_con / ecore_con_ssl.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #if USE_GNUTLS
6 # include <gnutls/gnutls.h>
7 # include <gnutls/x509.h>
8 # include <gcrypt.h>
9 #elif USE_OPENSSL
10 # include <openssl/ssl.h>
11 # include <openssl/err.h>
12 # include <openssl/dh.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 EAPI int ECORE_CON_EVENT_CLIENT_UPGRADE = 0;
23 EAPI int ECORE_CON_EVENT_SERVER_UPGRADE = 0;
24
25 static int _init_con_ssl_init_count = 0;
26
27 #ifdef USE_GNUTLS
28 # ifdef EINA_HAVE_THREADS
29 GCRY_THREAD_OPTION_PTHREAD_IMPL;
30 # endif
31
32 static int _client_connected = 0;
33
34 # define SSL_SUFFIX(ssl_func) ssl_func ## _gnutls
35 # define _ECORE_CON_SSL_AVAILABLE 1
36
37 #elif USE_OPENSSL
38
39 # define SSL_SUFFIX(ssl_func) ssl_func ## _openssl
40 # define _ECORE_CON_SSL_AVAILABLE 2
41
42 #else
43 # define SSL_SUFFIX(ssl_func) ssl_func ## _none
44 # define _ECORE_CON_SSL_AVAILABLE 0
45
46 #endif
47
48 #if USE_GNUTLS
49 static void
50 _gnutls_print_errors(void *conn, int type, int ret)
51 {
52    char buf[1024];
53
54    if (!ret) return;
55
56    snprintf(buf, sizeof(buf), "GNUTLS error: %s - %s", gnutls_strerror_name(ret), gnutls_strerror(ret));
57    if (type == ECORE_CON_EVENT_CLIENT_ERROR)
58      ecore_con_event_client_error(conn, buf);
59    else
60      ecore_con_event_server_error(conn, buf);
61 }
62
63 #ifdef ISCOMFITOR
64 static void
65 _gnutls_log_func(int         level,
66                  const char *str)
67 {
68    DBG("|<%d>| %s", level, str);
69 }
70 #endif
71
72 static const char *
73 SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_description_t status)
74 {
75    switch (status)
76      {
77       case GNUTLS_HANDSHAKE_HELLO_REQUEST:
78         return "Hello request";
79
80       case GNUTLS_HANDSHAKE_CLIENT_HELLO:
81         return "Client hello";
82
83       case GNUTLS_HANDSHAKE_SERVER_HELLO:
84         return "Server hello";
85
86       case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET:
87         return "New session ticket";
88
89       case GNUTLS_HANDSHAKE_CERTIFICATE_PKT:
90         return "Certificate packet";
91
92       case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE:
93         return "Server key exchange";
94
95       case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST:
96         return "Certificate request";
97
98       case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE:
99         return "Server hello done";
100
101       case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY:
102         return "Certificate verify";
103
104       case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
105         return "Client key exchange";
106
107       case GNUTLS_HANDSHAKE_FINISHED:
108         return "Finished";
109
110       case GNUTLS_HANDSHAKE_SUPPLEMENTAL:
111         return "Supplemental";
112      }
113    return NULL;
114 }
115
116 #elif USE_OPENSSL
117
118 static void
119 _openssl_print_errors(void *conn, int type)
120 {
121    char buf[1024];
122    do
123      {
124         unsigned long err;
125
126         err = ERR_get_error();
127         if (!err) break;
128         snprintf(buf, sizeof(buf), "OpenSSL error: %s", ERR_reason_error_string(err));
129         if (type == ECORE_CON_EVENT_CLIENT_ERROR)
130           ecore_con_event_client_error(conn, buf);
131         else
132           ecore_con_event_server_error(conn, buf);
133
134      } while (1);
135 }
136
137 static Eina_Bool
138 _openssl_name_verify(const char *name, const char *svrname)
139 {
140    if (name[0] == '*')
141      {
142         /* we allow *.domain.TLD with a wildcard, but nothing else */
143         const char *p, *s;
144
145         EINA_SAFETY_ON_TRUE_RETURN_VAL((name[1] != '.') || (!name[2]), EINA_FALSE);
146         p = strchr(name + 1, '*');
147         EINA_SAFETY_ON_TRUE_RETURN_VAL(!!p, EINA_FALSE);
148         /* verify that we have a domain of at least *.X.TLD and not *.TLD */
149         p = strchr(name + 2, '.');
150         EINA_SAFETY_ON_TRUE_RETURN_VAL(!p, EINA_FALSE);
151         s = strchr(svrname, '.');
152         EINA_SAFETY_ON_TRUE_RETURN_VAL(!s, EINA_FALSE);
153         /* same as above for the stored name */
154         EINA_SAFETY_ON_TRUE_RETURN_VAL(!strchr(s + 1, '.'), EINA_FALSE);
155         EINA_SAFETY_ON_TRUE_RETURN_VAL(strcasecmp(s, name + 1), EINA_FALSE);
156      }
157    else
158      EINA_SAFETY_ON_TRUE_RETURN_VAL(strcasecmp(name, svrname), EINA_FALSE);
159    return EINA_TRUE;
160 }
161
162 #endif
163
164 #define SSL_ERROR_CHECK_GOTO_ERROR(X)                                           \
165   do                                                                            \
166     {                                                                           \
167        if ((X))                                                                 \
168          {                                                                      \
169             ERR("Error at %s:%s:%d!", __FILE__, __PRETTY_FUNCTION__, __LINE__); \
170             goto error;                                                         \
171          }                                                                      \
172     }                                                                           \
173   while (0)
174
175 static Ecore_Con_Ssl_Error
176                            SSL_SUFFIX(_ecore_con_ssl_init) (void);
177 static Ecore_Con_Ssl_Error
178                            SSL_SUFFIX(_ecore_con_ssl_shutdown) (void);
179
180 static Eina_Bool           SSL_SUFFIX(_ecore_con_ssl_server_cafile_add) (Ecore_Con_Server * svr, const char *ca_file);
181 static Eina_Bool           SSL_SUFFIX(_ecore_con_ssl_server_crl_add) (Ecore_Con_Server * svr, const char *crl_file);
182 static Eina_Bool           SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (Ecore_Con_Server * svr, const char *cert);
183 static Eina_Bool           SSL_SUFFIX(_ecore_con_ssl_server_privkey_add) (Ecore_Con_Server * svr, const char *key_file);
184
185 static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_server_prepare) (Ecore_Con_Server * svr, int ssl_type);
186 static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_server_init) (Ecore_Con_Server * svr);
187 static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_server_shutdown) (Ecore_Con_Server *svr);
188 static int SSL_SUFFIX(_ecore_con_ssl_server_read) (Ecore_Con_Server *svr, unsigned char *buf, int size);
189 static int SSL_SUFFIX(_ecore_con_ssl_server_write) (Ecore_Con_Server *svr, const unsigned char *buf, int size);
190
191 static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_client_init) (Ecore_Con_Client * cl);
192 static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_client_shutdown) (Ecore_Con_Client *cl);
193 static int SSL_SUFFIX(_ecore_con_ssl_client_read) (Ecore_Con_Client * cl,
194                                         unsigned char *buf, int size);
195 static int SSL_SUFFIX(_ecore_con_ssl_client_write) (Ecore_Con_Client * cl,
196                                          const unsigned char *buf, int size);
197
198 /*
199  * General SSL API
200  */
201
202 Ecore_Con_Ssl_Error
203 ecore_con_ssl_init(void)
204 {
205    if (!_init_con_ssl_init_count++)
206      {
207         SSL_SUFFIX(_ecore_con_ssl_init) ();
208 #if _ECORE_CON_SSL_AVAILABLE != 0
209         ECORE_CON_EVENT_CLIENT_UPGRADE = ecore_event_type_new();
210         ECORE_CON_EVENT_SERVER_UPGRADE = ecore_event_type_new();
211 #endif
212      }
213
214    return _init_con_ssl_init_count;
215 }
216
217 Ecore_Con_Ssl_Error
218 ecore_con_ssl_shutdown(void)
219 {
220    if (!--_init_con_ssl_init_count)
221      SSL_SUFFIX(_ecore_con_ssl_shutdown) ();
222
223    return _init_con_ssl_init_count;
224 }
225
226 Ecore_Con_Ssl_Error
227 ecore_con_ssl_server_prepare(Ecore_Con_Server *svr,
228                              int               ssl_type)
229 {
230    if (!ssl_type)
231      return ECORE_CON_SSL_ERROR_NONE;
232    return SSL_SUFFIX(_ecore_con_ssl_server_prepare) (svr, ssl_type);
233 }
234
235 Ecore_Con_Ssl_Error
236 ecore_con_ssl_server_init(Ecore_Con_Server *svr)
237 {
238    if (!(svr->type & ECORE_CON_SSL))
239      return ECORE_CON_SSL_ERROR_NONE;
240    return SSL_SUFFIX(_ecore_con_ssl_server_init) (svr);
241 }
242
243 Ecore_Con_Ssl_Error
244 ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr)
245 {
246    if (!(svr->type & ECORE_CON_SSL))
247      return ECORE_CON_SSL_ERROR_NONE;
248    return SSL_SUFFIX(_ecore_con_ssl_server_shutdown) (svr);
249 }
250
251 int
252 ecore_con_ssl_server_read(Ecore_Con_Server *svr,
253                           unsigned char    *buf,
254                           int               size)
255 {
256    return SSL_SUFFIX(_ecore_con_ssl_server_read) (svr, buf, size);
257 }
258
259 int
260 ecore_con_ssl_server_write(Ecore_Con_Server *svr,
261                            const unsigned char *buf,
262                            int               size)
263 {
264    return SSL_SUFFIX(_ecore_con_ssl_server_write) (svr, buf, size);
265 }
266
267 Ecore_Con_Ssl_Error
268 ecore_con_ssl_client_init(Ecore_Con_Client *cl)
269 {
270    if (!(cl->host_server->type & ECORE_CON_SSL))
271      return ECORE_CON_SSL_ERROR_NONE;
272    return SSL_SUFFIX(_ecore_con_ssl_client_init) (cl);
273 }
274
275 Ecore_Con_Ssl_Error
276 ecore_con_ssl_client_shutdown(Ecore_Con_Client *cl)
277 {
278    if (!(cl->host_server->type & ECORE_CON_SSL))
279      return ECORE_CON_SSL_ERROR_NONE;
280    return SSL_SUFFIX(_ecore_con_ssl_client_shutdown) (cl);
281 }
282
283 int
284 ecore_con_ssl_client_read(Ecore_Con_Client *cl,
285                           unsigned char    *buf,
286                           int               size)
287 {
288    return SSL_SUFFIX(_ecore_con_ssl_client_read) (cl, buf, size);
289 }
290
291 int
292 ecore_con_ssl_client_write(Ecore_Con_Client *cl,
293                            const unsigned char *buf,
294                            int               size)
295 {
296    return SSL_SUFFIX(_ecore_con_ssl_client_write) (cl, buf, size);
297 }
298
299 /**
300  * Returns if SSL support is available
301  * @return 1 if SSL is available and provided by gnutls, 2 if provided by openssl,
302  * 0 if it is not available.
303  * @ingroup Ecore_Con_Client_Group
304  */
305 EAPI int
306 ecore_con_ssl_available_get(void)
307 {
308    return _ECORE_CON_SSL_AVAILABLE;
309 }
310
311 /**
312  * @addtogroup Ecore_Con_SSL_Group Ecore Connection SSL Functions
313  *
314  * Functions that operate on Ecore connection objects pertaining to SSL.
315  *
316  * @{
317  */
318
319 /**
320  * @brief Enable certificate verification on a server object
321  *
322  * Call this function on a server object before main loop has started
323  * to enable verification of certificates against loaded certificates.
324  * @param svr The server object
325  */
326 EAPI void
327 ecore_con_ssl_server_verify(Ecore_Con_Server *svr)
328 {
329    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
330      {
331         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_verify");
332         return;
333      }
334    svr->verify = EINA_TRUE;
335 }
336
337 /**
338  * @brief Enable hostname-based certificate verification on a server object
339  *
340  * Call this function on a server object before main loop has started
341  * to enable verification of certificates using ONLY their hostnames.
342  * @param svr The server object
343  * @note This function has no effect when used on a listening server created by
344  * ecore_con_server_add
345  * @since 1.1
346  */
347 EAPI void
348 ecore_con_ssl_server_verify_basic(Ecore_Con_Server *svr)
349 {
350    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
351      {
352         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
353         return;
354      }
355    svr->verify_basic = EINA_TRUE;
356 }
357
358 /**
359  * @brief Add an ssl certificate for use in ecore_con functions.
360  *
361  * Use this function to add a SSL PEM certificate.
362  * Simply specify the cert here to use it in the server object for connecting or listening.
363  * If there is an error loading the certificate, an error will automatically be logged.
364  * @param cert The path to the certificate.
365  * @return EINA_FALSE if the file cannot be loaded, otherwise EINA_TRUE.
366  */
367
368 EAPI Eina_Bool
369 ecore_con_ssl_server_cert_add(Ecore_Con_Server *svr,
370                               const char       *cert)
371 {
372    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
373      {
374         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_cert_add");
375         return EINA_FALSE;
376      }
377
378    if (!svr->ssl_prepared)
379      {
380         svr->use_cert = EINA_TRUE;
381         svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
382         if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
383           return EINA_FALSE;
384      }
385
386    return SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (svr, cert);
387 }
388
389 /**
390  * @brief Add an ssl CA file for use in ecore_con functions.
391  *
392  * Use this function to add a SSL PEM CA file.
393  * Simply specify the file here to use it in the server object for connecting or listening.
394  * If there is an error loading the CAs, an error will automatically be logged.
395  * @param ca_file The path to the CA file.
396  * @return EINA_FALSE if the file cannot be loaded, otherwise EINA_TRUE.
397  */
398
399 EAPI Eina_Bool
400 ecore_con_ssl_server_cafile_add(Ecore_Con_Server *svr,
401                                 const char       *ca_file)
402 {
403    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
404      {
405         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_cafile_add");
406         return EINA_FALSE;
407      }
408
409    if (!svr->ssl_prepared)
410      {
411         svr->use_cert = EINA_TRUE;
412         svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
413         if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
414           return EINA_FALSE;
415      }
416
417    return SSL_SUFFIX(_ecore_con_ssl_server_cafile_add) (svr, ca_file);
418 }
419
420 /**
421  * @brief Add an ssl private key for use in ecore_con functions.
422  *
423  * Use this function to add a SSL PEM private key
424  * Simply specify the key file here to use it in the server object for connecting or listening.
425  * If there is an error loading the key, an error will automatically be logged.
426  * @param key_file The path to the key file.
427  * @return EINA_FALSE if the file cannot be loaded,
428  * otherwise EINA_TRUE.
429  */
430
431 EAPI Eina_Bool
432 ecore_con_ssl_server_privkey_add(Ecore_Con_Server *svr,
433                                  const char       *key_file)
434 {
435    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
436      {
437         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_privkey_add");
438         return EINA_FALSE;
439      }
440
441    if (!svr->ssl_prepared)
442      {
443         svr->use_cert = EINA_TRUE;
444         svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
445         if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
446           return EINA_FALSE;
447      }
448
449    return SSL_SUFFIX(_ecore_con_ssl_server_privkey_add) (svr, key_file);
450 }
451
452 /**
453  * @brief Add an ssl CRL for use in ecore_con functions.
454  *
455  * Use this function to add a SSL PEM CRL file
456  * Simply specify the CRL file here to use it in the server object for connecting or listening.
457  * If there is an error loading the CRL, an error will automatically be logged.
458  * @param crl_file The path to the CRL file.
459  * @return EINA_FALSE if the file cannot be loaded,
460  * otherwise EINA_TRUE.
461  */
462
463 EAPI Eina_Bool
464 ecore_con_ssl_server_crl_add(Ecore_Con_Server *svr,
465                              const char       *crl_file)
466 {
467    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
468      {
469         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_crl_add");
470         return EINA_FALSE;
471      }
472
473    if (!svr->ssl_prepared)
474      {
475         svr->use_cert = EINA_TRUE;
476         svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
477         if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
478           return EINA_FALSE;
479      }
480
481    return SSL_SUFFIX(_ecore_con_ssl_server_crl_add) (svr, crl_file);
482 }
483
484 /**
485  * @brief Upgrade a connection to a specified level of encryption
486  *
487  * Use this function to begin an SSL handshake on a connection (STARTTLS or similar).
488  * Once the upgrade has been completed, an ECORE_CON_EVENT_SERVER_UPGRADE event will be emitted.
489  * The connection should be treated as disconnected until the next event.
490  * @param svr The server object
491  * @param ssl_type The SSL connection type (ONLY).
492  * @return EINA_FALSE if the connection cannot be upgraded, otherwise EINA_TRUE.
493  * @note This function is NEVER to be used on a server object created with ecore_con_server_add
494  * @warning Setting a wrong value for @p compl_type WILL mess up your program.
495  * @since 1.1
496  */
497
498 EAPI Eina_Bool
499 ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type ssl_type)
500 {
501    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
502      {
503         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
504         return EINA_FALSE;
505      }
506 #if _ECORE_CON_SSL_AVAILABLE == 0
507    return EINA_FALSE;
508 #endif
509
510    if (!svr->ssl_prepared)
511      {
512         if (ecore_con_ssl_server_prepare(svr, ssl_type))
513           return EINA_FALSE;
514      }
515    if (!svr->use_cert)
516      svr->type |= ssl_type;
517    svr->upgrade = EINA_TRUE;
518    svr->handshaking = EINA_TRUE;
519    svr->ssl_state = ECORE_CON_SSL_STATE_INIT;
520    return !SSL_SUFFIX(_ecore_con_ssl_server_init) (svr);
521 }
522
523 /**
524  * @brief Upgrade a connection to a specified level of encryption
525  *
526  * Use this function to begin an SSL handshake on a connection (STARTTLS or similar).
527  * Once the upgrade has been completed, an ECORE_CON_EVENT_CLIENT_UPGRADE event will be emitted.
528  * The connection should be treated as disconnected until the next event.
529  * @param cl The client object
530  * @param compl_type The SSL connection type (ONLY).
531  * @return EINA_FALSE if the connection cannot be upgraded, otherwise EINA_TRUE.
532  * @warning Setting a wrong value for @p compl_type WILL mess up your program.
533  * @since 1.1
534  */
535
536 EAPI Eina_Bool
537 ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type ssl_type)
538 {
539    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
540      {
541         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, __func__);
542         return EINA_FALSE;
543      }
544 #if _ECORE_CON_SSL_AVAILABLE == 0
545    return EINA_FALSE;
546 #endif
547
548    if (!cl->host_server->ssl_prepared)
549      {
550         if (ecore_con_ssl_server_prepare(cl->host_server, ssl_type))
551           return EINA_FALSE;
552      }
553    if (!cl->host_server->use_cert)
554      cl->host_server->type |= ssl_type;
555    cl->upgrade = EINA_TRUE;
556    cl->host_server->upgrade = EINA_TRUE;
557    cl->handshaking = EINA_TRUE;
558    cl->ssl_state = ECORE_CON_SSL_STATE_INIT;
559    return SSL_SUFFIX(_ecore_con_ssl_client_init) (cl);
560 }
561
562 /**
563  * @}
564  */
565
566 #if USE_GNUTLS
567
568 /*
569  * GnuTLS
570  */
571
572 static Ecore_Con_Ssl_Error
573 _ecore_con_ssl_init_gnutls(void)
574 {
575 #ifdef EINA_HAVE_THREADS
576    if (gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread))
577      WRN("YOU ARE USING PTHREADS, BUT I CANNOT INITIALIZE THREADSAFE GCRYPT OPERATIONS!");
578 #endif
579    if (gnutls_global_init())
580      return ECORE_CON_SSL_ERROR_INIT_FAILED;
581
582 #ifdef ISCOMFITOR
583    gnutls_global_set_log_level(9);
584    gnutls_global_set_log_function(_gnutls_log_func);
585 #endif
586    return ECORE_CON_SSL_ERROR_NONE;
587 }
588
589 static Ecore_Con_Ssl_Error
590 _ecore_con_ssl_shutdown_gnutls(void)
591 {
592    gnutls_global_deinit();
593
594    return ECORE_CON_SSL_ERROR_NONE;
595 }
596
597 static Ecore_Con_Ssl_Error
598 _ecore_con_ssl_server_prepare_gnutls(Ecore_Con_Server *svr,
599                                      int               ssl_type)
600 {
601    int ret;
602
603    if (ssl_type & ECORE_CON_USE_SSL2)
604      return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
605
606    switch (ssl_type)
607      {
608       case ECORE_CON_USE_SSL3:
609       case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
610       case ECORE_CON_USE_TLS:
611       case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
612       case ECORE_CON_USE_MIXED:
613       case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
614         break;
615
616       default:
617         return ECORE_CON_SSL_ERROR_NONE;
618      }
619
620    SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_allocate_credentials(&svr->cert));
621
622    if (svr->use_cert)
623      {
624         if  (svr->created)
625           {
626              SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_dh_params_init(&svr->dh_params));
627              INF("Generating DH params");
628              SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_dh_params_generate2(svr->dh_params, 1024));
629
630              SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_anon_allocate_server_credentials(&svr->anoncred_s));
631              /* TODO: implement PSK */
632              //  SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_psk_allocate_server_credentials(&svr->pskcred_s));
633
634              gnutls_anon_set_server_dh_params(svr->anoncred_s, svr->dh_params);
635              gnutls_certificate_set_dh_params(svr->cert, svr->dh_params);
636              //gnutls_psk_set_server_dh_params(svr->pskcred_s, svr->dh_params);
637              INF("DH params successfully generated and applied!");
638           }
639       else
640         {
641            //SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_psk_allocate_client_credentials(&svr->pskcred_c));
642              SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_anon_allocate_client_credentials(&svr->anoncred_c));
643         }
644      }
645
646    svr->ssl_prepared = EINA_TRUE;
647    return ECORE_CON_SSL_ERROR_NONE;
648
649 error:
650    _gnutls_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR, ret);
651    _ecore_con_ssl_server_shutdown_gnutls(svr);
652    return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
653 }
654
655
656 static Ecore_Con_Ssl_Error
657 _ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr)
658 {
659    const gnutls_datum_t *cert_list;
660    unsigned int iter, cert_list_size;
661    gnutls_x509_crt_t cert = NULL;
662    const char *priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0";
663    int ret = 0;
664
665    switch (svr->ssl_state)
666      {
667       case ECORE_CON_SSL_STATE_DONE:
668         return ECORE_CON_SSL_ERROR_NONE;
669
670       case ECORE_CON_SSL_STATE_INIT:
671         if (svr->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */
672           return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
673
674         switch (svr->type & ECORE_CON_SSL)
675           {
676            case ECORE_CON_USE_SSL3:
677            case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
678              priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-TLS1.0:!VERS-TLS1.1";
679              break;
680
681            case ECORE_CON_USE_TLS:
682            case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
683              priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-SSL3.0";
684              break;
685
686            case ECORE_CON_USE_MIXED:
687            case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
688              break;
689
690            default:
691              return ECORE_CON_SSL_ERROR_NONE;
692           }
693
694         SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&svr->session, GNUTLS_CLIENT));
695         SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_enable_client(svr->session));
696         SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_server_name_set(svr->session, GNUTLS_NAME_DNS, svr->name, strlen(svr->name)));
697         INF("Applying priority string: %s", priority);
698         SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_priority_set_direct(svr->session, priority, NULL));
699         SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_CERTIFICATE, svr->cert));
700         // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_PSK, svr->pskcred_c));
701         if (!svr->use_cert)
702           SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_ANON, svr->anoncred_c));
703
704         gnutls_dh_set_prime_bits(svr->session, 512);
705         gnutls_transport_set_ptr(svr->session, (gnutls_transport_ptr_t)((intptr_t)svr->fd));
706         svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
707
708       case ECORE_CON_SSL_STATE_HANDSHAKING:
709         if (!svr->session)
710           {
711              DBG("Server was previously lost, going to error condition");
712              goto error;
713           }
714         ret = gnutls_handshake(svr->session);
715         DBG("calling gnutls_handshake(): returned with '%s'", gnutls_strerror_name(ret));
716         SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret));
717         if (!ret)
718           {
719              svr->handshaking = EINA_FALSE;
720              svr->ssl_state = ECORE_CON_SSL_STATE_DONE;
721           }
722         else
723           {
724              if (gnutls_record_get_direction(svr->session))
725                ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
726              else
727                ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
728              return ECORE_CON_SSL_ERROR_NONE;
729           }
730
731       default:
732         break;
733      }
734
735    if ((!svr->verify) && (!svr->verify_basic))
736      /* not verifying certificates, so we're done! */
737      return ECORE_CON_SSL_ERROR_NONE;
738    if (svr->verify)
739      {
740         /* use CRL/CA lists to verify */
741         SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_verify_peers2(svr->session, &iter));
742         if (iter & GNUTLS_CERT_INVALID)
743           ERR("The certificate is not trusted.");
744         else if (iter & GNUTLS_CERT_SIGNER_NOT_FOUND)
745           ERR("The certificate hasn't got a known issuer.");
746         else if (iter & GNUTLS_CERT_REVOKED)
747           ERR("The certificate has been revoked.");
748         else if (iter & GNUTLS_CERT_EXPIRED)
749           ERR("The certificate has expired");
750         else if (iter & GNUTLS_CERT_NOT_ACTIVATED)
751           ERR("The certificate is not yet activated");
752
753         if (iter)
754           goto error;
755      }
756    if (gnutls_certificate_type_get(svr->session) != GNUTLS_CRT_X509)
757      {
758         ERR("Warning: PGP certificates are not yet supported!");
759         goto error;
760      }
761
762    SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(svr->session, &cert_list_size)));
763    SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size);
764
765    SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert));
766    SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER));
767
768    SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, svr->name));
769    gnutls_x509_crt_deinit(cert);
770    DBG("SSL certificate verification succeeded!");
771    return ECORE_CON_SSL_ERROR_NONE;
772
773 error:
774    _gnutls_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR, ret);
775    if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED))
776      ERR("Also received alert: %s", gnutls_alert_get_name(gnutls_alert_get(svr->session)));
777    if (svr->session && (svr->ssl_state != ECORE_CON_SSL_STATE_DONE))
778      {
779         ERR("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_out(svr->session)));
780         ERR("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_in(svr->session)));
781      }
782    if (cert)
783      gnutls_x509_crt_deinit(cert);
784    _ecore_con_ssl_server_shutdown_gnutls(svr);
785    return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
786 }
787
788 static Eina_Bool
789 _ecore_con_ssl_server_cafile_add_gnutls(Ecore_Con_Server *svr,
790                                         const char       *ca_file)
791 {
792    SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_trust_file(svr->cert, ca_file,
793                                                                      GNUTLS_X509_FMT_PEM) < 1);
794
795    return EINA_TRUE;
796 error:
797    ERR("Could not load CA file!");
798    return EINA_FALSE;
799 }
800
801 static Eina_Bool
802 _ecore_con_ssl_server_crl_add_gnutls(Ecore_Con_Server *svr,
803                                      const char       *crl_file)
804 {
805    SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_crl_file(svr->cert, crl_file,
806                                                                    GNUTLS_X509_FMT_PEM) < 1);
807
808    return EINA_TRUE;
809 error:
810    ERR("Could not load CRL file!");
811    return EINA_FALSE;
812 }
813
814 static Eina_Bool
815 _ecore_con_ssl_server_privkey_add_gnutls(Ecore_Con_Server *svr,
816                                          const char       *key_file)
817 {
818    SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_key_file(svr->cert, svr->cert_file, key_file,
819                                                                    GNUTLS_X509_FMT_PEM));
820
821    return EINA_TRUE;
822 error:
823    ERR("Could not load certificate/key file!");
824    return EINA_FALSE;
825 }
826
827 static Eina_Bool
828 _ecore_con_ssl_server_cert_add_gnutls(Ecore_Con_Server *svr,
829                                       const char       *cert_file)
830 {
831    if (!(svr->cert_file = strdup(cert_file)))
832      return EINA_FALSE;
833
834    return EINA_TRUE;
835 }
836
837 static Ecore_Con_Ssl_Error
838 _ecore_con_ssl_server_shutdown_gnutls(Ecore_Con_Server *svr)
839 {
840    if (svr->session)
841      {
842         gnutls_bye(svr->session, GNUTLS_SHUT_RDWR);
843         gnutls_deinit(svr->session);
844      }
845
846    free(svr->cert_file);
847    svr->cert_file = NULL;
848    if (svr->cert)
849      gnutls_certificate_free_credentials(svr->cert);
850    svr->cert = NULL;
851
852    if ((svr->type & ECORE_CON_SSL) && svr->created)
853      {
854         if (svr->dh_params)
855           {
856              gnutls_dh_params_deinit(svr->dh_params);
857              svr->dh_params = NULL;
858           }
859         if (svr->anoncred_s)
860           gnutls_anon_free_server_credentials(svr->anoncred_s);
861         //  if (svr->pskcred_s)
862         //   gnutls_psk_free_server_credentials(svr->pskcred_s);
863
864         svr->anoncred_s = NULL;
865         svr->pskcred_s = NULL;
866      }
867    else if (svr->type & ECORE_CON_SSL)
868      {
869         if (svr->anoncred_c)
870           gnutls_anon_free_client_credentials(svr->anoncred_c);
871         // if (svr->pskcred_c)
872         // gnutls_psk_free_client_credentials(svr->pskcred_c);
873
874         svr->anoncred_c = NULL;
875         svr->pskcred_c = NULL;
876      }
877
878    svr->session = NULL;
879
880    return ECORE_CON_SSL_ERROR_NONE;
881 }
882
883 static int
884 _ecore_con_ssl_server_read_gnutls(Ecore_Con_Server *svr,
885                                   unsigned char    *buf,
886                                   int               size)
887 {
888    int num;
889
890    if (svr->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING)
891      {
892         DBG("Continuing gnutls handshake");
893         if (!_ecore_con_ssl_server_init_gnutls(svr))
894           return 0;
895         return -1;
896      }
897
898    num = gnutls_record_recv(svr->session, buf, size);
899    if (num > 0)
900      return num;
901
902    if (num == GNUTLS_E_REHANDSHAKE)
903      {
904         WRN("Rehandshake request ignored");
905         return 0;
906
907         svr->handshaking = EINA_TRUE;
908         svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
909         if (!_ecore_con_ssl_server_init_gnutls(svr))
910           return 0;
911      }
912    else if ((!gnutls_error_is_fatal(num)) && (num != GNUTLS_E_SUCCESS))
913      return 0;
914
915    return -1;
916 }
917
918 static int
919 _ecore_con_ssl_server_write_gnutls(Ecore_Con_Server *svr,
920                                    const unsigned char *buf,
921                                    int               size)
922 {
923    int num;
924
925    if (svr->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING)
926      {
927         DBG("Continuing gnutls handshake");
928         if (!_ecore_con_ssl_server_init_gnutls(svr))
929           return 0;
930         return -1;
931      }
932
933    num = gnutls_record_send(svr->session, buf, size);
934    if (num > 0)
935      return num;
936
937    if (num == GNUTLS_E_REHANDSHAKE)
938      {
939         WRN("Rehandshake request ignored");
940         return 0;
941 /* this is only partly functional I think? */
942         svr->handshaking = EINA_TRUE;
943         svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
944         if (!_ecore_con_ssl_server_init_gnutls(svr))
945           return 0;
946      }
947    else if (!gnutls_error_is_fatal(num))
948      return 0;
949
950    return -1;
951 }
952
953 static Ecore_Con_Ssl_Error
954 _ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
955 {
956    const gnutls_datum_t *cert_list;
957    unsigned int iter, cert_list_size;
958    const char *priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0";
959    int ret = 0;
960
961    switch (cl->ssl_state)
962      {
963       case ECORE_CON_SSL_STATE_DONE:
964         return ECORE_CON_SSL_ERROR_NONE;
965
966       case ECORE_CON_SSL_STATE_INIT:
967         if (cl->host_server->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */
968           return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
969
970         switch (cl->host_server->type & ECORE_CON_SSL)
971           {
972            case ECORE_CON_USE_SSL3:
973            case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
974              priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-TLS1.0:!VERS-TLS1.1";
975              break;
976
977            case ECORE_CON_USE_TLS:
978            case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
979              priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-SSL3.0";
980              break;
981
982            case ECORE_CON_USE_MIXED:
983            case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
984              break;
985
986            default:
987              return ECORE_CON_SSL_ERROR_NONE;
988           }
989
990         _client_connected++;
991
992         SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&cl->session, GNUTLS_SERVER));
993         SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_key_generate(&cl->session_ticket));
994         SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_enable_server(cl->session, &cl->session_ticket));
995         INF("Applying priority string: %s", priority);
996         SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_priority_set_direct(cl->session, priority, NULL));
997         SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_CERTIFICATE, cl->host_server->cert));
998         //  SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_PSK, cl->host_server->pskcred_s));
999         if (!cl->host_server->use_cert)
1000           SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_ANON, cl->host_server->anoncred_s));
1001
1002         gnutls_certificate_server_set_request(cl->session, GNUTLS_CERT_REQUEST);
1003
1004         gnutls_dh_set_prime_bits(cl->session, 2048);
1005         gnutls_transport_set_ptr(cl->session, (gnutls_transport_ptr_t)((intptr_t)cl->fd));
1006         cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1007
1008       case ECORE_CON_SSL_STATE_HANDSHAKING:
1009         if (!cl->session)
1010           {
1011              DBG("Client was previously lost, going to error condition");
1012              goto error;
1013           }
1014         DBG("calling gnutls_handshake()");
1015         ret = gnutls_handshake(cl->session);
1016         SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret));
1017
1018         if (!ret)
1019           {
1020              cl->handshaking = EINA_FALSE;
1021              cl->ssl_state = ECORE_CON_SSL_STATE_DONE;
1022           }
1023         else
1024           {
1025              if (gnutls_record_get_direction(cl->session))
1026                ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
1027              else
1028                ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
1029              return ECORE_CON_SSL_ERROR_NONE;
1030           }
1031
1032       default:
1033         break;
1034      }
1035
1036    if (!cl->host_server->verify)
1037      /* not verifying certificates, so we're done! */
1038      return ECORE_CON_SSL_ERROR_NONE;
1039    /* use CRL/CA lists to verify */
1040    SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_verify_peers2(cl->session, &iter));
1041    if (iter & GNUTLS_CERT_INVALID)
1042      ERR("The certificate is not trusted.");
1043    else if (iter & GNUTLS_CERT_SIGNER_NOT_FOUND)
1044      ERR("The certificate hasn't got a known issuer.");
1045    else if (iter & GNUTLS_CERT_REVOKED)
1046      ERR("The certificate has been revoked.");
1047    else if (iter & GNUTLS_CERT_EXPIRED)
1048      ERR("The certificate has expired");
1049    else if (iter & GNUTLS_CERT_NOT_ACTIVATED)
1050      ERR("The certificate is not yet activated");
1051
1052    if (iter)
1053      goto error;
1054    if (gnutls_certificate_type_get(cl->session) != GNUTLS_CRT_X509)
1055      {
1056         ERR("Warning: PGP certificates are not yet supported!");
1057         goto error;
1058      }
1059
1060    SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(cl->session, &cert_list_size)));
1061    SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size);
1062
1063 /*
1064    gnutls_x509_crt_t cert = NULL;
1065    SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert));
1066    SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER));
1067
1068    SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, cl->host_server->name));
1069    gnutls_x509_crt_deinit(cert);
1070 */
1071    DBG("SSL certificate verification succeeded!");
1072    return ECORE_CON_SSL_ERROR_NONE;
1073
1074 error:
1075    _gnutls_print_errors(cl, ECORE_CON_EVENT_CLIENT_ERROR, ret);
1076    if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED))
1077      ERR("Also received alert: %s", gnutls_alert_get_name(gnutls_alert_get(cl->session)));
1078    if (cl->session && (cl->ssl_state != ECORE_CON_SSL_STATE_DONE))
1079      {
1080         ERR("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_out(cl->session)));
1081         ERR("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_in(cl->session)));
1082      }
1083 /*
1084    if (cert)
1085      gnutls_x509_crt_deinit(cert);
1086 */
1087    _ecore_con_ssl_client_shutdown_gnutls(cl);
1088    return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
1089 }
1090
1091 static Ecore_Con_Ssl_Error
1092 _ecore_con_ssl_client_shutdown_gnutls(Ecore_Con_Client *cl)
1093 {
1094    if (cl->session)
1095      {
1096         gnutls_bye(cl->session, GNUTLS_SHUT_RDWR);
1097         gnutls_deinit(cl->session);
1098         gnutls_free(cl->session_ticket.data);
1099         cl->session_ticket.data = NULL;
1100      }
1101
1102    cl->session = NULL;
1103
1104    return ECORE_CON_SSL_ERROR_NONE;
1105 }
1106
1107 static int
1108 _ecore_con_ssl_client_read_gnutls(Ecore_Con_Client *cl,
1109                                   unsigned char    *buf,
1110                                   int               size)
1111 {
1112    int num;
1113
1114    if (cl->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING)
1115      {
1116         if (!_ecore_con_ssl_client_init_gnutls(cl))
1117           return 0;
1118         return -1;
1119      }
1120
1121    num = gnutls_record_recv(cl->session, buf, size);
1122    if (num > 0)
1123      return num;
1124
1125    if (num == GNUTLS_E_REHANDSHAKE)
1126      {
1127         WRN("Rehandshake request ignored");
1128         return 0;
1129         cl->handshaking = EINA_TRUE;
1130         cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1131         if (!_ecore_con_ssl_client_init_gnutls(cl))
1132           return 0;
1133         WRN("Rehandshake request ignored");
1134         return 0;
1135      }
1136    else if ((!gnutls_error_is_fatal(num)) && (num != GNUTLS_E_SUCCESS))
1137      return 0;
1138
1139    return -1;
1140 }
1141
1142 static int
1143 _ecore_con_ssl_client_write_gnutls(Ecore_Con_Client *cl,
1144                                    const unsigned char *buf,
1145                                    int               size)
1146 {
1147    int num;
1148
1149    if (cl->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING)
1150      {
1151         if (!_ecore_con_ssl_client_init_gnutls(cl))
1152           return 0;
1153         return -1;
1154      }
1155
1156    num = gnutls_record_send(cl->session, buf, size);
1157    if (num > 0)
1158      return num;
1159
1160    if (num == GNUTLS_E_REHANDSHAKE)
1161      {
1162         WRN("Rehandshake request ignored");
1163         return 0;
1164         cl->handshaking = EINA_TRUE;
1165         cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1166         if (!_ecore_con_ssl_client_init_gnutls(cl))
1167           return 0;
1168      }
1169    else if (!gnutls_error_is_fatal(num))
1170      return 0;
1171
1172    return -1;
1173 }
1174
1175 #elif USE_OPENSSL && !USE_GNUTLS
1176
1177 /*
1178  * OpenSSL
1179  */
1180
1181 static Ecore_Con_Ssl_Error
1182 _ecore_con_ssl_init_openssl(void)
1183 {
1184    SSL_library_init();
1185    SSL_load_error_strings();
1186    OpenSSL_add_all_algorithms();
1187
1188    return ECORE_CON_SSL_ERROR_NONE;
1189 }
1190
1191 static Ecore_Con_Ssl_Error
1192 _ecore_con_ssl_shutdown_openssl(void)
1193 {
1194    ERR_free_strings();
1195    EVP_cleanup();
1196    return ECORE_CON_SSL_ERROR_NONE;
1197 }
1198
1199 static Ecore_Con_Ssl_Error
1200 _ecore_con_ssl_server_prepare_openssl(Ecore_Con_Server *svr,
1201                                       int               ssl_type)
1202 {
1203    long options;
1204    int dh = 0;
1205
1206    if (ssl_type & ECORE_CON_USE_SSL2)
1207      return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
1208
1209    switch (ssl_type)
1210      {
1211       case ECORE_CON_USE_SSL3:
1212       case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
1213         if (!svr->created)
1214           SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())));
1215         else
1216           SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_server_method())));
1217         break;
1218
1219       case ECORE_CON_USE_TLS:
1220       case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
1221         if (!svr->created)
1222           SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())));
1223         else
1224           SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_server_method())));
1225         break;
1226
1227       case ECORE_CON_USE_MIXED:
1228       case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
1229         if (!svr->created)
1230           SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_client_method())));
1231         else
1232           SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_server_method())));
1233         options = SSL_CTX_get_options(svr->ssl_ctx);
1234         SSL_CTX_set_options(svr->ssl_ctx, options | SSL_OP_NO_SSLv2 | SSL_OP_SINGLE_DH_USE);
1235         break;
1236
1237       default:
1238         return ECORE_CON_SSL_ERROR_NONE;
1239      }
1240
1241    if ((!svr->use_cert) && svr->created)
1242      {
1243         DH *dh_params;
1244         INF("Generating DH params");
1245         SSL_ERROR_CHECK_GOTO_ERROR(!(dh_params = DH_new()));
1246         SSL_ERROR_CHECK_GOTO_ERROR(!DH_generate_parameters_ex(dh_params, 1024, DH_GENERATOR_5, NULL));
1247         SSL_ERROR_CHECK_GOTO_ERROR(!DH_check(dh_params, &dh));
1248         SSL_ERROR_CHECK_GOTO_ERROR((dh & DH_CHECK_P_NOT_PRIME) || (dh & DH_CHECK_P_NOT_SAFE_PRIME));
1249         SSL_ERROR_CHECK_GOTO_ERROR(!DH_generate_key(dh_params));
1250         SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_tmp_dh(svr->ssl_ctx, dh_params));
1251         DH_free(dh_params);
1252         INF("DH params successfully generated and applied!");
1253         SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_cipher_list(svr->ssl_ctx, "aNULL:!eNULL:!LOW:!EXPORT:@STRENGTH"));
1254      }
1255    else if (!svr->use_cert)
1256      SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_cipher_list(svr->ssl_ctx, "aNULL:!eNULL:!LOW:!EXPORT:!ECDH:RSA:AES:!PSK:@STRENGTH"));
1257
1258    return ECORE_CON_SSL_ERROR_NONE;
1259
1260 error:
1261    if (dh)
1262      {
1263         if (dh & DH_CHECK_P_NOT_PRIME)
1264           ERR("openssl error: dh_params could not generate a prime!");
1265         else
1266           ERR("openssl error: dh_params could not generate a safe prime!");
1267      }
1268    else
1269      _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1270    _ecore_con_ssl_server_shutdown_openssl(svr);
1271    return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
1272 }
1273
1274 static Ecore_Con_Ssl_Error
1275 _ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr)
1276 {
1277    int ret = -1;
1278
1279    switch (svr->ssl_state)
1280      {
1281       case ECORE_CON_SSL_STATE_DONE:
1282         return ECORE_CON_SSL_ERROR_NONE;
1283
1284       case ECORE_CON_SSL_STATE_INIT:
1285         SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl = SSL_new(svr->ssl_ctx)));
1286
1287         SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(svr->ssl, svr->fd));
1288         SSL_set_connect_state(svr->ssl);
1289         svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1290
1291       case ECORE_CON_SSL_STATE_HANDSHAKING:
1292         if (!svr->ssl)
1293           {
1294              DBG("Server was previously lost, going to error condition");
1295              goto error;
1296           }
1297         ret = SSL_do_handshake(svr->ssl);
1298         svr->ssl_err = SSL_get_error(svr->ssl, ret);
1299         SSL_ERROR_CHECK_GOTO_ERROR((svr->ssl_err == SSL_ERROR_SYSCALL) || (svr->ssl_err == SSL_ERROR_SSL));
1300
1301         if (ret == 1)
1302           {
1303              svr->handshaking = EINA_FALSE;
1304              svr->ssl_state = ECORE_CON_SSL_STATE_DONE;
1305           }
1306         else
1307           {
1308              if (svr->ssl_err == SSL_ERROR_WANT_READ)
1309                ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1310              else if (svr->ssl_err == SSL_ERROR_WANT_WRITE)
1311                ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
1312              return ECORE_CON_SSL_ERROR_NONE;
1313           }
1314
1315       default:
1316         break;
1317      }
1318
1319 #ifdef ISCOMFITOR
1320    {
1321       /* print session info into DBG */
1322        SSL_SESSION *s;
1323        BIO *b;
1324        char log[4096];
1325
1326        memset(log, 0, sizeof(log));
1327        s = SSL_get_session(svr->ssl);
1328        b = BIO_new(BIO_s_mem());
1329        SSL_SESSION_print(b, s);
1330        while (BIO_read(b, log, sizeof(log)) > 0)
1331          DBG("%s", log);
1332
1333        BIO_free(b);
1334    }
1335 #endif
1336    if ((!svr->verify) && (!svr->verify_basic))
1337      /* not verifying certificates, so we're done! */
1338      return ECORE_CON_SSL_ERROR_NONE;
1339
1340    {
1341       X509 *cert;
1342       SSL_set_verify(svr->ssl, SSL_VERIFY_PEER, NULL);
1343       /* use CRL/CA lists to verify */
1344       cert = SSL_get_peer_certificate(svr->ssl);
1345       if (cert)
1346         {
1347            char buf[256] = {0};
1348            if (svr->verify)
1349              SSL_ERROR_CHECK_GOTO_ERROR(SSL_get_verify_result(svr->ssl));
1350            X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_subject_alt_name, buf, sizeof(buf));
1351            if (buf[0])
1352              SSL_ERROR_CHECK_GOTO_ERROR(!_openssl_name_verify(buf, svr->name));
1353            else
1354              {
1355                 X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, buf, sizeof(buf));
1356                 SSL_ERROR_CHECK_GOTO_ERROR(!_openssl_name_verify(buf, svr->name));
1357              }
1358         }
1359    }
1360
1361    DBG("SSL certificate verification succeeded!");
1362
1363    return ECORE_CON_SSL_ERROR_NONE;
1364
1365 error:
1366    _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1367    _ecore_con_ssl_server_shutdown_openssl(svr);
1368    return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
1369 }
1370
1371 static Eina_Bool
1372 _ecore_con_ssl_server_cafile_add_openssl(Ecore_Con_Server *svr,
1373                                          const char       *ca_file)
1374 {
1375    SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_load_verify_locations(svr->ssl_ctx, ca_file, NULL));
1376    return EINA_TRUE;
1377
1378 error:
1379    _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1380    return EINA_FALSE;
1381 }
1382
1383 static Eina_Bool
1384 _ecore_con_ssl_server_crl_add_openssl(Ecore_Con_Server *svr,
1385                                       const char       *crl_file)
1386 {
1387    X509_STORE *st;
1388    X509_LOOKUP *lu;
1389    static Eina_Bool flag = EINA_FALSE;
1390
1391    SSL_ERROR_CHECK_GOTO_ERROR(!(st = SSL_CTX_get_cert_store(svr->ssl_ctx)));
1392    SSL_ERROR_CHECK_GOTO_ERROR(!(lu = X509_STORE_add_lookup(st, X509_LOOKUP_file())));
1393    SSL_ERROR_CHECK_GOTO_ERROR(X509_load_crl_file(lu, crl_file, X509_FILETYPE_PEM) < 1);
1394    if (!flag)
1395      {
1396         X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
1397         flag = EINA_TRUE;
1398      }
1399
1400    return EINA_TRUE;
1401
1402 error:
1403    _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1404    return EINA_FALSE;
1405 }
1406
1407 static Eina_Bool
1408 _ecore_con_ssl_server_privkey_add_openssl(Ecore_Con_Server *svr,
1409                                           const char       *key_file)
1410 {
1411    FILE *fp = NULL;
1412    EVP_PKEY *privkey = NULL;
1413
1414    if (!(fp = fopen(key_file, "r")))
1415      goto error;
1416
1417    SSL_ERROR_CHECK_GOTO_ERROR(!(privkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL)));
1418
1419    fclose(fp);
1420    SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_PrivateKey(svr->ssl_ctx, privkey) < 1);
1421    SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_check_private_key(svr->ssl_ctx) < 1);
1422
1423    return EINA_TRUE;
1424
1425 error:
1426    if (fp)
1427      fclose(fp);
1428    _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1429    return EINA_FALSE;
1430 }
1431
1432 static Eina_Bool
1433 _ecore_con_ssl_server_cert_add_openssl(Ecore_Con_Server *svr,
1434                                        const char       *cert_file)
1435 {
1436    FILE *fp = NULL;
1437    X509 *cert = NULL;
1438
1439    if (!(fp = fopen(cert_file, "r")))
1440      goto error;
1441
1442    SSL_ERROR_CHECK_GOTO_ERROR(!(cert = PEM_read_X509(fp, NULL, NULL, NULL)));
1443
1444    fclose(fp);
1445
1446    SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_certificate(svr->ssl_ctx, cert) < 1);
1447
1448    return EINA_TRUE;
1449
1450 error:
1451    if (fp)
1452      fclose(fp);
1453    _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1454    return EINA_FALSE;
1455 }
1456
1457 static Ecore_Con_Ssl_Error
1458 _ecore_con_ssl_server_shutdown_openssl(Ecore_Con_Server *svr)
1459 {
1460    if (svr->ssl)
1461      {
1462         if (!SSL_shutdown(svr->ssl))
1463           SSL_shutdown(svr->ssl);
1464
1465         SSL_free(svr->ssl);
1466      }
1467
1468    if (svr->ssl_ctx)
1469      SSL_CTX_free(svr->ssl_ctx);
1470
1471    svr->ssl = NULL;
1472    svr->ssl_ctx = NULL;
1473    svr->ssl_err = SSL_ERROR_NONE;
1474
1475    return ECORE_CON_SSL_ERROR_NONE;
1476 }
1477
1478 static int
1479 _ecore_con_ssl_server_read_openssl(Ecore_Con_Server *svr,
1480                                    unsigned char    *buf,
1481                                    int               size)
1482 {
1483    int num;
1484
1485    if (!svr->ssl) return -1;
1486    num = SSL_read(svr->ssl, buf, size);
1487    svr->ssl_err = SSL_get_error(svr->ssl, num);
1488
1489    if (svr->fd_handler)
1490      {
1491         if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ)
1492           ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1493         else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE)
1494           ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
1495      }
1496
1497    if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
1498        (svr->ssl_err == SSL_ERROR_SYSCALL) ||
1499        (svr->ssl_err == SSL_ERROR_SSL))
1500      return -1;
1501
1502    if (num < 0)
1503      return 0;
1504
1505    return num;
1506 }
1507
1508 static int
1509 _ecore_con_ssl_server_write_openssl(Ecore_Con_Server *svr,
1510                                     const unsigned char *buf,
1511                                     int               size)
1512 {
1513    int num;
1514
1515    num = SSL_write(svr->ssl, buf, size);
1516    svr->ssl_err = SSL_get_error(svr->ssl, num);
1517
1518    if (svr->fd_handler)
1519      {
1520         if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ)
1521           ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1522         else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE)
1523           ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
1524      }
1525
1526    if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
1527        (svr->ssl_err == SSL_ERROR_SYSCALL) ||
1528        (svr->ssl_err == SSL_ERROR_SSL))
1529      return -1;
1530
1531    if (num < 0)
1532      return 0;
1533
1534    return num;
1535 }
1536
1537 static Ecore_Con_Ssl_Error
1538 _ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl)
1539 {
1540    int ret = -1;
1541    switch (cl->ssl_state)
1542      {
1543       case ECORE_CON_SSL_STATE_DONE:
1544         return ECORE_CON_SSL_ERROR_NONE;
1545
1546       case ECORE_CON_SSL_STATE_INIT:
1547         SSL_ERROR_CHECK_GOTO_ERROR(!(cl->ssl = SSL_new(cl->host_server->ssl_ctx)));
1548
1549         SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(cl->ssl, cl->fd));
1550         SSL_set_accept_state(cl->ssl);
1551         cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1552
1553       case ECORE_CON_SSL_STATE_HANDSHAKING:
1554          if (!cl->ssl)
1555           {
1556              DBG("Client was previously lost, going to error condition");
1557              goto error;
1558           }
1559         ret = SSL_do_handshake(cl->ssl);
1560         cl->ssl_err = SSL_get_error(cl->ssl, ret);
1561         SSL_ERROR_CHECK_GOTO_ERROR((cl->ssl_err == SSL_ERROR_SYSCALL) || (cl->ssl_err == SSL_ERROR_SSL));
1562         if (ret == 1)
1563           {
1564              cl->handshaking = EINA_FALSE;
1565              cl->ssl_state = ECORE_CON_SSL_STATE_DONE;
1566           }
1567         else
1568           {
1569              if (cl->ssl_err == SSL_ERROR_WANT_READ)
1570                ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
1571              else if (cl->ssl_err == SSL_ERROR_WANT_WRITE)
1572                ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
1573              return ECORE_CON_SSL_ERROR_NONE;
1574           }
1575
1576       default:
1577         break;
1578      }
1579
1580 #ifdef ISCOMFITOR
1581    {
1582       /* print session info into DBG */
1583        SSL_SESSION *s;
1584        BIO *b;
1585        char log[4096];
1586
1587        memset(log, 0, sizeof(log));
1588        s = SSL_get_session(cl->ssl);
1589        b = BIO_new(BIO_s_mem());
1590        SSL_SESSION_print(b, s);
1591        while (BIO_read(b, log, sizeof(log)) > 0)
1592          DBG("%s", log);
1593
1594        BIO_free(b);
1595    }
1596 #endif
1597
1598    if (!cl->host_server->verify)
1599      /* not verifying certificates, so we're done! */
1600      return ECORE_CON_SSL_ERROR_NONE;
1601    SSL_set_verify(cl->ssl, SSL_VERIFY_PEER, NULL);
1602    /* use CRL/CA lists to verify */
1603    if (SSL_get_peer_certificate(cl->ssl))
1604      SSL_ERROR_CHECK_GOTO_ERROR(SSL_get_verify_result(cl->ssl));
1605
1606    return ECORE_CON_SSL_ERROR_NONE;
1607
1608 error:
1609    _openssl_print_errors(cl, ECORE_CON_EVENT_CLIENT_ERROR);
1610    _ecore_con_ssl_client_shutdown_openssl(cl);
1611    return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
1612 }
1613
1614 static Ecore_Con_Ssl_Error
1615 _ecore_con_ssl_client_shutdown_openssl(Ecore_Con_Client *cl)
1616 {
1617    if (cl->ssl)
1618      {
1619         if (!SSL_shutdown(cl->ssl))
1620           SSL_shutdown(cl->ssl);
1621
1622         SSL_free(cl->ssl);
1623      }
1624
1625    cl->ssl = NULL;
1626    cl->ssl_err = SSL_ERROR_NONE;
1627
1628    return ECORE_CON_SSL_ERROR_NONE;
1629 }
1630
1631 static int
1632 _ecore_con_ssl_client_read_openssl(Ecore_Con_Client *cl,
1633                                    unsigned char    *buf,
1634                                    int               size)
1635 {
1636    int num;
1637
1638    if (!cl->ssl) return -1;
1639    num = SSL_read(cl->ssl, buf, size);
1640    cl->ssl_err = SSL_get_error(cl->ssl, num);
1641
1642    if (cl->fd_handler)
1643      {
1644         if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ)
1645           ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
1646         else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE)
1647           ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
1648      }
1649
1650    if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
1651        (cl->ssl_err == SSL_ERROR_SYSCALL) ||
1652        (cl->ssl_err == SSL_ERROR_SSL))
1653      return -1;
1654
1655    if (num < 0)
1656      return 0;
1657
1658    return num;
1659 }
1660
1661 static int
1662 _ecore_con_ssl_client_write_openssl(Ecore_Con_Client *cl,
1663                                     const unsigned char *buf,
1664                                     int               size)
1665 {
1666    int num;
1667
1668    num = SSL_write(cl->ssl, buf, size);
1669    cl->ssl_err = SSL_get_error(cl->ssl, num);
1670
1671    if (cl->fd_handler)
1672      {
1673         if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ)
1674           ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
1675         else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE)
1676           ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
1677      }
1678
1679    if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
1680        (cl->ssl_err == SSL_ERROR_SYSCALL) ||
1681        (cl->ssl_err == SSL_ERROR_SSL))
1682      return -1;
1683
1684    if (num < 0)
1685      return 0;
1686
1687    return num;
1688 }
1689
1690 #else
1691
1692 /*
1693  * No Ssl
1694  */
1695
1696 static Ecore_Con_Ssl_Error
1697 _ecore_con_ssl_init_none(void)
1698 {
1699    return ECORE_CON_SSL_ERROR_NONE;
1700 }
1701
1702 static Ecore_Con_Ssl_Error
1703 _ecore_con_ssl_shutdown_none(void)
1704 {
1705    return ECORE_CON_SSL_ERROR_NONE;
1706 }
1707
1708 static Ecore_Con_Ssl_Error
1709 _ecore_con_ssl_server_prepare_none(Ecore_Con_Server *svr __UNUSED__,
1710                                    int ssl_type          __UNUSED__)
1711 {
1712    return ECORE_CON_SSL_ERROR_NONE;
1713 }
1714
1715 static Ecore_Con_Ssl_Error
1716 _ecore_con_ssl_server_init_none(Ecore_Con_Server *svr __UNUSED__)
1717 {
1718    return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
1719 }
1720
1721 static Eina_Bool
1722 _ecore_con_ssl_server_cafile_add_none(Ecore_Con_Server *svr __UNUSED__,
1723                                       const char *ca_file   __UNUSED__)
1724 {
1725    return EINA_FALSE;
1726 }
1727
1728 static Eina_Bool
1729 _ecore_con_ssl_server_cert_add_none(Ecore_Con_Server *svr __UNUSED__,
1730                                     const char *cert_file __UNUSED__)
1731 {
1732    return EINA_FALSE;
1733 }
1734
1735 static Eina_Bool
1736 _ecore_con_ssl_server_privkey_add_none(Ecore_Con_Server *svr __UNUSED__,
1737                                        const char *key_file  __UNUSED__)
1738 {
1739    return EINA_FALSE;
1740 }
1741
1742 static Eina_Bool
1743 _ecore_con_ssl_server_crl_add_none(Ecore_Con_Server *svr __UNUSED__,
1744                                    const char *crl_file  __UNUSED__)
1745 {
1746    return EINA_FALSE;
1747 }
1748
1749 static Ecore_Con_Ssl_Error
1750 _ecore_con_ssl_server_shutdown_none(Ecore_Con_Server *svr __UNUSED__)
1751 {
1752    return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
1753 }
1754
1755 static int
1756 _ecore_con_ssl_server_read_none(Ecore_Con_Server *svr __UNUSED__,
1757                                 unsigned char *buf    __UNUSED__,
1758                                 int size              __UNUSED__)
1759 {
1760    return -1;
1761 }
1762
1763 static int
1764 _ecore_con_ssl_server_write_none(Ecore_Con_Server *svr __UNUSED__,
1765                                  const unsigned char *buf __UNUSED__,
1766                                  int size              __UNUSED__)
1767 {
1768    return -1;
1769 }
1770
1771 static Ecore_Con_Ssl_Error
1772 _ecore_con_ssl_client_init_none(Ecore_Con_Client *cl __UNUSED__)
1773 {
1774    return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
1775 }
1776
1777 static Ecore_Con_Ssl_Error
1778 _ecore_con_ssl_client_shutdown_none(Ecore_Con_Client *cl __UNUSED__)
1779 {
1780    return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
1781 }
1782
1783 static int
1784 _ecore_con_ssl_client_read_none(Ecore_Con_Client *cl __UNUSED__,
1785                                 unsigned char *buf   __UNUSED__,
1786                                 int size             __UNUSED__)
1787 {
1788    return -1;
1789 }
1790
1791 static int
1792 _ecore_con_ssl_client_write_none(Ecore_Con_Client *cl __UNUSED__,
1793                                  const unsigned char *buf __UNUSED__,
1794                                  int size             __UNUSED__)
1795 {
1796    return -1;
1797 }
1798
1799 #endif