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