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