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