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