31469f2257417bcbab6baaebe4ac4853ca507411
[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 #endif
13
14 #ifdef HAVE_WS2TCPIP_H
15 # include <ws2tcpip.h>
16 #endif
17
18 #include "Ecore.h"
19 #include "ecore_con_private.h"
20 #include <sys/mman.h>
21 #include <errno.h>
22
23 static int _init_con_ssl_init_count = 0;
24
25 #if USE_GNUTLS
26 # ifdef EFL_HAVE_PTHREAD
27 GCRY_THREAD_OPTION_PTHREAD_IMPL;
28 # endif
29
30 static int _client_connected = 0;
31 # define SSL_SUFFIX(ssl_func) ssl_func ## _gnutls
32 # define _ECORE_CON_SSL_AVAILABLE 1
33
34 #elif USE_OPENSSL
35
36 # define SSL_SUFFIX(ssl_func) ssl_func ## _openssl
37 # define _ECORE_CON_SSL_AVAILABLE 2
38
39 #else
40 # define SSL_SUFFIX(ssl_func) ssl_func ## _none
41 # define _ECORE_CON_SSL_AVAILABLE 0
42
43 #endif
44
45 #if USE_GNUTLS
46 typedef struct _cert_thingy
47 {
48    gnutls_certificate_credentials_t cert;
49    int count;
50 } gnutls;
51 static gnutls *client_cert = NULL;
52 static gnutls *server_cert = NULL;
53 #elif USE_OPENSSL
54 typedef struct _cert_thingy
55 {
56    X509 *cert;
57    int count;
58 } openssl;
59 typedef struct _key_thingy
60 {
61    EVP_PKEY *key;
62    int count;
63 } openssl_pkey;
64 static openssl_pkey *private_key = NULL;
65 static openssl *client_cert = NULL;
66 static openssl *server_cert = NULL;
67 #endif
68
69 static Ecore_Con_Ssl_Error
70                  SSL_SUFFIX(_ecore_con_ssl_init) (void);
71 static Ecore_Con_Ssl_Error
72                  SSL_SUFFIX(_ecore_con_ssl_shutdown) (void);
73
74 static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_client_cert_add) (const char *
75                                                              cert_file,
76                                                              const char *
77                                                              crl_file,
78                                                              const char *
79                                                              key_file);
80 static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (const char *cert);
81
82 static void      SSL_SUFFIX(_ecore_con_ssl_server_prepare) (Ecore_Con_Server *
83                                                             svr);
84 static Ecore_Con_Ssl_Error
85                  SSL_SUFFIX(_ecore_con_ssl_server_init) (Ecore_Con_Server * svr);
86 static Ecore_Con_Ssl_Error
87                  SSL_SUFFIX(_ecore_con_ssl_server_shutdown) (Ecore_Con_Server *
88                                             svr);
89 static Ecore_Con_State
90                  SSL_SUFFIX(_ecore_con_ssl_server_try) (Ecore_Con_Server * svr);
91 static int
92                  SSL_SUFFIX(_ecore_con_ssl_server_read) (Ecore_Con_Server * svr,
93                                         unsigned char *buf, int size);
94 static int
95                  SSL_SUFFIX(_ecore_con_ssl_server_write) (Ecore_Con_Server *
96                                          svr,
97                                          unsigned char *buf, int size);
98
99 static void
100                  SSL_SUFFIX(_ecore_con_ssl_client_prepare) (Ecore_Con_Client *
101                                            cl);
102 static Ecore_Con_Ssl_Error
103                  SSL_SUFFIX(_ecore_con_ssl_client_init) (Ecore_Con_Client * cl);
104 static Ecore_Con_Ssl_Error
105                  SSL_SUFFIX(_ecore_con_ssl_client_shutdown) (Ecore_Con_Client *
106                                             cl);
107 static int
108                  SSL_SUFFIX(_ecore_con_ssl_client_read) (Ecore_Con_Client * cl,
109                                         unsigned char *buf, int size);
110 static int
111                  SSL_SUFFIX(_ecore_con_ssl_client_write) (Ecore_Con_Client * cl,
112                                          unsigned char *buf, int size);
113
114 /*
115  * General SSL API
116  */
117
118 Ecore_Con_Ssl_Error
119 ecore_con_ssl_init(void)
120 {
121    if (!_init_con_ssl_init_count++)
122         SSL_SUFFIX(_ecore_con_ssl_init) ();
123
124    return _init_con_ssl_init_count;
125 }
126
127 Ecore_Con_Ssl_Error
128 ecore_con_ssl_shutdown(void)
129 {
130    if (!--_init_con_ssl_init_count)
131      {
132 #if USE_OPENSSL || USE_GNUTLS
133         if (client_cert)
134            client_cert->count = 0;
135
136         if (server_cert)
137            server_cert->count = 0;
138 #endif
139 #if USE_OPENSSL && !USE_GNUTLS
140         if (private_key)
141            private_key->count = 0;
142
143 #endif
144         SSL_SUFFIX(_ecore_con_ssl_shutdown) ();
145      }
146
147    return _init_con_ssl_init_count;
148 }
149
150 /**
151  * Returns if SSL support is available
152  * @return  1 if SSL is available, 0 if it is not.
153  * @ingroup Ecore_Con_Client_Group
154  */
155 int
156 ecore_con_ssl_available_get(void)
157 {
158    return _ECORE_CON_SSL_AVAILABLE;
159 }
160
161
162 void
163 ecore_con_ssl_server_prepare(Ecore_Con_Server *svr)
164 {
165         SSL_SUFFIX(_ecore_con_ssl_server_prepare) (svr);
166 }
167
168 Ecore_Con_Ssl_Error
169 ecore_con_ssl_server_init(Ecore_Con_Server *svr)
170 {
171    return SSL_SUFFIX(_ecore_con_ssl_server_init) (svr);
172 }
173
174 Eina_Bool
175 ecore_con_ssl_server_cert_add(const char *cert)
176 {
177    return SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (cert);
178 }
179
180 Ecore_Con_Ssl_Error
181 ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr)
182 {
183    return SSL_SUFFIX(_ecore_con_ssl_server_shutdown) (svr);
184 }
185
186 Ecore_Con_State
187 ecore_con_ssl_server_try(Ecore_Con_Server *svr)
188 {
189    return SSL_SUFFIX(_ecore_con_ssl_server_try) (svr);
190 }
191
192 int
193 ecore_con_ssl_server_read(Ecore_Con_Server *svr, unsigned char *buf, int size)
194 {
195    return SSL_SUFFIX(_ecore_con_ssl_server_read) (svr, buf, size);
196 }
197
198 int
199 ecore_con_ssl_server_write(Ecore_Con_Server *svr, unsigned char *buf, int size)
200 {
201    return SSL_SUFFIX(_ecore_con_ssl_server_write) (svr, buf, size);
202 }
203
204 Ecore_Con_Ssl_Error
205 ecore_con_ssl_client_init(Ecore_Con_Client *cl)
206 {
207    return SSL_SUFFIX(_ecore_con_ssl_client_init) (cl);
208 }
209
210 Eina_Bool
211 ecore_con_ssl_client_cert_add(const char *cert_file,
212                               const char *crl_file,
213                               const char *key_file)
214 {
215    return SSL_SUFFIX(_ecore_con_ssl_client_cert_add) (cert_file, crl_file,
216                                                       key_file);
217 }
218
219 Ecore_Con_Ssl_Error
220 ecore_con_ssl_client_shutdown(Ecore_Con_Client *cl)
221 {
222    return SSL_SUFFIX(_ecore_con_ssl_client_shutdown) (cl);
223 }
224
225 int
226 ecore_con_ssl_client_read(Ecore_Con_Client *cl, unsigned char *buf, int size)
227 {
228    return SSL_SUFFIX(_ecore_con_ssl_client_read) (cl, buf, size);
229 }
230
231 int
232 ecore_con_ssl_client_write(Ecore_Con_Client *cl, unsigned char *buf, int size)
233 {
234    return SSL_SUFFIX(_ecore_con_ssl_client_write) (cl, buf, size);
235 }
236
237 #if USE_GNUTLS
238
239 /*
240  * GnuTLS
241  */
242
243 static Ecore_Con_Ssl_Error
244 _ecore_con_ssl_init_gnutls(void)
245 {
246 #ifdef EFL_HAVE_PTHREAD
247    if (gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread))
248       WRN(
249          "YOU ARE USING PTHREADS, BUT I CANNOT INITIALIZE THREADSAFE GCRYPT OPERATIONS!");
250
251 #endif
252    if (gnutls_global_init())
253       return ECORE_CON_SSL_ERROR_INIT_FAILED;
254
255    return ECORE_CON_SSL_ERROR_NONE;
256 }
257
258 static Ecore_Con_Ssl_Error
259 _ecore_con_ssl_shutdown_gnutls(void)
260 {
261    gnutls_global_deinit();
262
263    return ECORE_CON_SSL_ERROR_NONE;
264 }
265
266 static void
267 _ecore_con_ssl_server_prepare_gnutls(Ecore_Con_Server *svr)
268 {
269    svr->session = NULL;
270    svr->anoncred_c = NULL;
271    return;
272 }
273
274 /* Tries to connect an Ecore_Con_Server to an SSL host.
275  * Returns 1 on success, -1 on fatal errors and 0 if the caller
276  * should try again later.
277  */
278 static Ecore_Con_Ssl_Error
279 _ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr)
280 {
281    const int *proto = NULL;
282    int ret = 0;
283    const int kx[] = { GNUTLS_KX_ANON_DH, 0 };
284    const int ssl3_proto[] = { GNUTLS_SSL3, 0 };
285    const int tls_proto[] = {
286       GNUTLS_TLS1_0,
287       GNUTLS_TLS1_1,
288 #ifdef USE_GNUTLS2
289       GNUTLS_TLS1_2,
290 #endif
291       0
292    };
293
294    switch (svr->type & ECORE_CON_SSL)
295      {
296       case ECORE_CON_USE_SSL2: /* not supported because of security issues */
297          return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
298
299       case ECORE_CON_USE_SSL3:
300          proto = ssl3_proto;
301          break;
302
303       case ECORE_CON_USE_TLS:
304          proto = tls_proto;
305          break;
306
307       default:
308          return ECORE_CON_SSL_ERROR_NONE;
309      }
310
311    if ((server_cert) && (server_cert->cert) &&
312        ((svr->type & ECORE_CON_TYPE) & ECORE_CON_LOAD_CERT))
313      {
314         svr->cert = server_cert->cert;
315         server_cert->count++;
316      }
317
318    gnutls_init(&(svr->session), GNUTLS_CLIENT);
319    gnutls_set_default_priority(svr->session);
320    gnutls_kx_set_priority(svr->session, kx);
321    if (svr->cert)
322       gnutls_credentials_set(svr->session, GNUTLS_CRD_CERTIFICATE,
323                              svr->cert);
324    else
325      {
326         gnutls_anon_allocate_client_credentials(&svr->anoncred_c);
327         gnutls_credentials_set(svr->session, GNUTLS_CRD_ANON, svr->anoncred_c);
328      }
329
330    gnutls_kx_set_priority(svr->session, kx);
331    gnutls_protocol_set_priority(svr->session, proto);
332    gnutls_dh_set_prime_bits(svr->session, 2048);
333
334    gnutls_transport_set_ptr(svr->session, (gnutls_transport_ptr_t)svr->fd);
335
336    while ((ret = gnutls_handshake(svr->session)) < 0)
337      {
338         if ((ret == GNUTLS_E_AGAIN) ||
339             (ret == GNUTLS_E_INTERRUPTED))
340            continue;
341
342         _ecore_con_ssl_server_shutdown_gnutls(svr);
343         return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
344      }
345
346    return ECORE_CON_SSL_ERROR_NONE;
347 }
348
349 static Eina_Bool
350 _ecore_con_ssl_server_cert_add_gnutls(const char *cert_file)
351 {
352    gnutls_certificate_credentials_t cert = NULL;
353
354    /* cert load */
355    if (gnutls_certificate_set_x509_trust_file(cert, cert_file,
356                                               GNUTLS_X509_FMT_PEM) < 0)
357       goto on_error;
358
359    if (!server_cert)
360      {
361         server_cert = malloc(sizeof(gnutls));
362         if (!server_cert)
363            return EINA_FALSE;
364      }
365    else if ((server_cert->cert) && ((--server_cert->count) < 1))
366       gnutls_certificate_free_credentials(server_cert->cert);
367
368    server_cert->cert = cert;
369    server_cert->count = 1;
370
371    return EINA_TRUE;
372
373 on_error:
374    if (cert)
375       gnutls_certificate_free_credentials(cert);
376
377    return EINA_FALSE;
378 }
379
380 static Ecore_Con_Ssl_Error
381 _ecore_con_ssl_server_shutdown_gnutls(Ecore_Con_Server *svr)
382 {
383    if (svr->session)
384      {
385         gnutls_bye(svr->session, GNUTLS_SHUT_RDWR);
386         gnutls_deinit(svr->session);
387      }
388
389    if (((svr->type & ECORE_CON_TYPE) & ECORE_CON_LOAD_CERT) &&
390        (server_cert) &&
391        (server_cert->cert) && (--server_cert->count < 1))
392      {
393         gnutls_certificate_free_credentials(server_cert->cert);
394         free(server_cert);
395         server_cert = NULL;
396      }
397    else if (svr->anoncred_c)
398       gnutls_anon_free_client_credentials(svr->anoncred_c);
399
400    _ecore_con_ssl_server_prepare_gnutls(svr);
401
402    return ECORE_CON_SSL_ERROR_NONE;
403 }
404
405 /* this is a stub function, the handshake is done in _init_gnutls */
406 static Ecore_Con_State
407 _ecore_con_ssl_server_try_gnutls(Ecore_Con_Server *svr __UNUSED__)
408 {
409    return ECORE_CON_CONNECTED;
410 }
411
412 static int
413 _ecore_con_ssl_server_read_gnutls(Ecore_Con_Server *svr, unsigned char *buf,
414                                   int size)
415 {
416    int num;
417
418    num = gnutls_record_recv(svr->session, buf, size);
419    if (num > 0)
420       return num;
421
422    if ((num == GNUTLS_E_AGAIN) ||
423        (num == GNUTLS_E_REHANDSHAKE) ||
424        (num == GNUTLS_E_INTERRUPTED))
425       return 0;
426
427    return -1;
428 }
429
430 static int
431 _ecore_con_ssl_server_write_gnutls(Ecore_Con_Server *svr, unsigned char *buf,
432                                    int size)
433 {
434    int num;
435
436    num = gnutls_record_send(svr->session, buf, size);
437    if (num > 0)
438       return num;
439
440    if ((num == GNUTLS_E_AGAIN) ||
441        (num == GNUTLS_E_REHANDSHAKE) ||
442        (num == GNUTLS_E_INTERRUPTED))
443       return 0;
444
445    return -1;
446 }
447
448 static void
449 _ecore_con_ssl_client_prepare_gnutls(Ecore_Con_Client *cl)
450 {
451    cl->session = NULL;
452    if (!_client_connected)
453      {
454         cl->server->anoncred_s = NULL;
455         cl->server->cert = NULL;
456      }
457 }
458
459 static Ecore_Con_Ssl_Error
460 _ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
461 {
462    const int *proto = NULL;
463    gnutls_dh_params_t dh_params;
464    int ret;
465    const int kx[] = { GNUTLS_KX_ANON_DH, 0 };
466    const int ssl3_proto[] = { GNUTLS_SSL3, 0 };
467    const int tls_proto[] = {
468       GNUTLS_TLS1_0,
469       GNUTLS_TLS1_1,
470 #ifdef USE_GNUTLS2
471       GNUTLS_TLS1_2,
472 #endif
473       0
474    };
475
476    switch (cl->server->type & ECORE_CON_SSL)
477      {
478       case ECORE_CON_USE_SSL2: /* not supported because of security issues */
479          return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
480
481       case ECORE_CON_USE_SSL3:
482          proto = ssl3_proto;
483          break;
484
485       case ECORE_CON_USE_TLS:
486          proto = tls_proto;
487          break;
488
489       default:
490          return ECORE_CON_SSL_ERROR_NONE;
491      }
492
493    _client_connected++;
494
495    gnutls_dh_params_init(&dh_params);
496    gnutls_dh_params_generate2(dh_params, 1024);
497
498    if ((client_cert) && (client_cert->cert) &&
499        ((cl->server->type & ECORE_CON_TYPE) & ECORE_CON_LOAD_CERT))
500      {
501         cl->server->cert = client_cert->cert;
502         client_cert->count++;
503         gnutls_certificate_set_dh_params(cl->server->cert, dh_params);
504      }
505
506    if ((!cl->server->anoncred_s) && (!cl->server->cert))
507      {
508         gnutls_anon_allocate_server_credentials(&(cl->server->anoncred_s));
509         gnutls_anon_set_server_dh_params(cl->server->anoncred_s, dh_params);
510      }
511
512    gnutls_init(&(cl->session), GNUTLS_SERVER);
513    gnutls_set_default_priority(cl->session);
514    if (cl->server->cert)
515      {
516         gnutls_credentials_set(cl->session,
517                                GNUTLS_CRD_CERTIFICATE,
518                                cl->server->cert);
519         gnutls_certificate_server_set_request(cl->session, GNUTLS_CERT_REQUEST);
520      }
521    else
522       gnutls_credentials_set(cl->session, GNUTLS_CRD_ANON,
523                              cl->server->anoncred_s);
524
525    gnutls_kx_set_priority(cl->session, kx);
526
527    gnutls_protocol_set_priority(cl->session, proto);
528
529    gnutls_transport_set_ptr(cl->session, (gnutls_transport_ptr_t)cl->fd);
530
531    while ((ret = gnutls_handshake(cl->session)) < 0)
532      {
533         if ((ret == GNUTLS_E_AGAIN) ||
534             (ret == GNUTLS_E_INTERRUPTED))
535            continue;
536
537         _ecore_con_ssl_client_shutdown_gnutls(cl);
538         return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
539      }
540
541    /* TODO: add cert verification support */
542    return ECORE_CON_SSL_ERROR_NONE;
543 }
544
545 static Ecore_Con_Ssl_Error
546 _ecore_con_ssl_client_shutdown_gnutls(Ecore_Con_Client *cl)
547 {
548    if (cl->session)
549      {
550         gnutls_bye(cl->session, GNUTLS_SHUT_RDWR);
551         gnutls_deinit(cl->session);
552      }
553
554    if (cl->server->anoncred_s && !--_client_connected)
555       gnutls_anon_free_server_credentials(cl->server->anoncred_s);
556
557    if (((cl->server->type & ECORE_CON_TYPE) & ECORE_CON_LOAD_CERT) &&
558        (client_cert) &&
559        (client_cert->cert) && (--client_cert->count < 1))
560      {
561         gnutls_certificate_free_credentials(client_cert->cert);
562         free(client_cert);
563         client_cert = NULL;
564      }
565
566    _ecore_con_ssl_client_prepare_gnutls(cl);
567
568    return ECORE_CON_SSL_ERROR_NONE;
569 }
570
571 static Eina_Bool
572 _ecore_con_ssl_client_cert_add_gnutls(const char *cert_file,
573                                       const char *crl_file,
574                                       const char *key_file)
575 {
576    gnutls_certificate_credentials_t cert = NULL;
577
578    if (gnutls_certificate_allocate_credentials(&cert) < 0)
579       return EINA_FALSE;
580
581    /* cert load */
582    if (gnutls_certificate_set_x509_trust_file(cert, cert_file,
583                                               GNUTLS_X509_FMT_PEM) < 0)
584       goto on_error;
585
586    /* private key load */
587    if (gnutls_certificate_set_x509_key_file(cert, cert_file, key_file,
588                                             GNUTLS_X509_FMT_PEM) < 0)
589       goto on_error;
590
591 #if 0
592    //TODO: uncomment once we implement cert checking
593    if (crl_file)
594       /* CRL file load */
595       if (gnutls_certificate_set_x509_crl_mem(cert, crl_file,
596                                               GNUTLS_X509_FMT_PEM) < 0)
597          goto on_error;
598
599 }
600 #endif
601    if (!client_cert)
602      {
603         client_cert = malloc(sizeof(gnutls));
604         if (!client_cert)
605            return EINA_FALSE;
606      }
607    else if ((client_cert->cert) && ((--client_cert->count) < 1))
608       gnutls_certificate_free_credentials(client_cert->cert);
609
610    client_cert->cert = cert;
611    client_cert->count = 1;
612
613    return EINA_TRUE;
614
615 on_error:
616    if (cert)
617       gnutls_certificate_free_credentials(cert);
618
619    return EINA_FALSE;
620 }
621
622 static int
623 _ecore_con_ssl_client_read_gnutls(Ecore_Con_Client *cl, unsigned char *buf,
624                                   int size)
625 {
626    int num;
627
628    num = gnutls_record_recv(cl->session, buf, size);
629    if (num > 0)
630       return num;
631
632    if ((num == GNUTLS_E_AGAIN) ||
633        (num == GNUTLS_E_REHANDSHAKE) ||
634        (num == GNUTLS_E_INTERRUPTED))
635       return 0;
636
637    return -1;
638 }
639
640 static int
641 _ecore_con_ssl_client_write_gnutls(Ecore_Con_Client *cl, unsigned char *buf,
642                                    int size)
643 {
644    int num;
645
646    num = gnutls_record_send(cl->session, buf, size);
647    if (num > 0)
648       return num;
649
650    if ((num == GNUTLS_E_AGAIN) ||
651        (num == GNUTLS_E_REHANDSHAKE) ||
652        (num == GNUTLS_E_INTERRUPTED))
653       return 0;
654
655    return -1;
656 }
657
658 #elif USE_OPENSSL && !USE_GNUTLS
659
660 /*
661  * OpenSSL
662  */
663
664 static Ecore_Con_Ssl_Error
665 _ecore_con_ssl_init_openssl(void)
666 {
667    SSL_library_init();
668    SSL_load_error_strings();
669
670    return ECORE_CON_SSL_ERROR_NONE;
671 }
672
673 static Ecore_Con_Ssl_Error
674 _ecore_con_ssl_shutdown_openssl(void)
675 {
676    ERR_free_strings();
677    return ECORE_CON_SSL_ERROR_NONE;
678 }
679
680 static void
681 _ecore_con_ssl_server_prepare_openssl(Ecore_Con_Server *svr)
682 {
683    svr->ssl = NULL;
684    svr->ssl_ctx = NULL;
685    svr->ssl_err = SSL_ERROR_NONE;
686 }
687
688 static Ecore_Con_Ssl_Error
689 _ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr)
690 {
691    switch (svr->type & ECORE_CON_SSL)
692      {
693       case ECORE_CON_USE_SSL2:
694          /* Unsafe version of SSL */
695          if (!(svr->ssl_ctx =
696                   SSL_CTX_new(SSLv2_client_method())))
697             return
698                ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
699
700          break;
701
702       case ECORE_CON_USE_SSL3:
703          if (!(svr->ssl_ctx =
704                   SSL_CTX_new(SSLv3_client_method())))
705             return
706                ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
707
708          break;
709
710       case ECORE_CON_USE_TLS:
711          if (!(svr->ssl_ctx =
712                   SSL_CTX_new(TLSv1_client_method())))
713             return
714                ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
715
716          break;
717
718       default:
719          return ECORE_CON_SSL_ERROR_NONE;
720      }
721    if (!(svr->ssl = SSL_new(svr->ssl_ctx)))
722      {
723         SSL_CTX_free(svr->ssl_ctx);
724         return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
725      }
726
727    if ((server_cert) && (server_cert->cert) &&
728        ((svr->type & ECORE_CON_TYPE) & ECORE_CON_LOAD_CERT))
729      {
730         //FIXME: just log and go on without cert if loading fails?
731         if (!SSL_CTX_use_certificate(svr->ssl_ctx, server_cert->cert))
732            ERR(
733               "ssl cert load failed: %s", ERR_reason_error_string(ERR_get_error()));
734
735         server_cert->count++;
736      }
737
738    SSL_set_fd(svr->ssl, svr->fd);
739
740    return ECORE_CON_SSL_ERROR_NONE;
741 }
742
743 static Eina_Bool
744 _ecore_con_ssl_server_cert_add_openssl(const char *cert_file)
745 {
746    FILE *fp = NULL;
747    X509 *cert = NULL;
748
749    if (!(fp = fopen(cert_file, "r")))
750       goto on_error;
751
752    if (!(cert = PEM_read_X509(fp, NULL, NULL, NULL)))
753       goto on_error;
754
755    fclose(fp);
756
757    if (!server_cert)
758      {
759         server_cert = malloc(sizeof(openssl));
760         if (!server_cert)
761            return EINA_FALSE;
762      }
763    else if ((server_cert->cert) && ((--server_cert->count) < 1))
764       X509_free(server_cert->cert);
765
766    server_cert->cert = cert;
767
768    server_cert->count = 1;
769
770    return EINA_TRUE;
771
772 on_error:
773    if (fp)
774       fclose(fp);
775
776    return EINA_FALSE;
777 }
778
779 static Ecore_Con_Ssl_Error
780 _ecore_con_ssl_server_shutdown_openssl(Ecore_Con_Server *svr)
781 {
782    if (svr->ssl)
783      {
784         if (!SSL_shutdown(svr->ssl))
785            SSL_shutdown(svr->ssl);
786
787         SSL_free(svr->ssl);
788      }
789
790    if (((svr->type & ECORE_CON_TYPE) & ECORE_CON_LOAD_CERT) &&
791        (server_cert) && (server_cert->cert) &&
792        (--server_cert->count < 1))
793      {
794         X509_free(server_cert->cert);
795         free(server_cert);
796         server_cert = NULL;
797      }
798
799    if (svr->ssl_ctx)
800       SSL_CTX_free(svr->ssl_ctx);
801
802    _ecore_con_ssl_server_prepare_openssl(svr);
803
804    return ECORE_CON_SSL_ERROR_NONE;
805 }
806
807 /* Tries to connect an Ecore_Con_Server to an SSL host.
808  * Returns 1 on success, -1 on fatal errors and 0 if the caller
809  * should try again later.
810  */
811 static Ecore_Con_State
812 _ecore_con_ssl_server_try_openssl(Ecore_Con_Server *svr)
813 {
814    int res, flag = 0;
815
816    if ((res = SSL_connect(svr->ssl)) == 1)
817       return ECORE_CON_CONNECTED;
818
819    svr->ssl_err = SSL_get_error(svr->ssl, res);
820
821    switch (svr->ssl_err)
822      {
823       case SSL_ERROR_NONE:
824          return ECORE_CON_CONNECTED;
825
826       case SSL_ERROR_WANT_READ:
827          flag = ECORE_FD_READ;
828          break;
829
830       case SSL_ERROR_WANT_WRITE:
831          flag = ECORE_FD_WRITE;
832          break;
833
834       default:
835          return ECORE_CON_DISCONNECTED;
836      }
837
838    if (svr->fd_handler && flag)
839            ecore_main_fd_handler_active_set(svr->fd_handler,
840                                        flag);
841
842    return ECORE_CON_INPROGRESS;
843 }
844
845 static int
846 _ecore_con_ssl_server_read_openssl(Ecore_Con_Server *svr, unsigned char *buf,
847                                    int size)
848 {
849    int num;
850
851    num = SSL_read(svr->ssl, buf, size);
852    svr->ssl_err = SSL_get_error(svr->ssl, num);
853
854    if (svr->fd_handler)
855      {
856         if (svr->ssl && svr->ssl_err ==
857             SSL_ERROR_WANT_READ)
858            ecore_main_fd_handler_active_set(svr->fd_handler,
859                                             ECORE_FD_READ);
860         else if (svr->ssl && svr->ssl_err ==
861                  SSL_ERROR_WANT_WRITE)
862            ecore_main_fd_handler_active_set(
863               svr->fd_handler,
864               ECORE_FD_WRITE);
865      }
866
867    if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
868        (svr->ssl_err == SSL_ERROR_SYSCALL) ||
869        (svr->ssl_err == SSL_ERROR_SSL))
870       return -1;
871
872    if (num < 0)
873       return 0;
874
875    return num;
876 }
877
878 static int
879 _ecore_con_ssl_server_write_openssl(Ecore_Con_Server *svr, unsigned char *buf,
880                                     int size)
881 {
882    int num;
883
884    num = SSL_write(svr->ssl, buf, size);
885    svr->ssl_err = SSL_get_error(svr->ssl, num);
886
887    if (svr->fd_handler)
888      {
889         if (svr->ssl && svr->ssl_err ==
890             SSL_ERROR_WANT_READ)
891            ecore_main_fd_handler_active_set(svr->fd_handler,
892                                             ECORE_FD_READ);
893         else if (svr->ssl && svr->ssl_err ==
894                  SSL_ERROR_WANT_WRITE)
895            ecore_main_fd_handler_active_set(
896               svr->fd_handler,
897               ECORE_FD_WRITE);
898      }
899
900    if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
901        (svr->ssl_err == SSL_ERROR_SYSCALL) ||
902        (svr->ssl_err == SSL_ERROR_SSL))
903       return -1;
904
905    if (num < 0)
906       return 0;
907
908    return num;
909 }
910
911 static void
912 _ecore_con_ssl_client_prepare_openssl(Ecore_Con_Client *cl)
913 {
914    cl->ssl = NULL;
915    cl->ssl_ctx = NULL;
916    cl->ssl_err = SSL_ERROR_NONE;
917 }
918
919 static Ecore_Con_Ssl_Error
920 _ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl)
921 {
922    switch (cl->server->type & ECORE_CON_SSL)
923      {
924       case ECORE_CON_USE_SSL2:
925          /* Unsafe version of SSL */
926          if (!(cl->ssl_ctx =
927                   SSL_CTX_new(SSLv2_client_method())))
928             return
929                ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
930
931          break;
932
933       case ECORE_CON_USE_SSL3:
934          if (!(cl->ssl_ctx =
935                   SSL_CTX_new(SSLv3_client_method())))
936             return
937                ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
938
939          break;
940
941       case ECORE_CON_USE_TLS:
942          if (!(cl->ssl_ctx =
943                   SSL_CTX_new(TLSv1_client_method())))
944             return
945                ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
946
947          break;
948
949       default:
950          return ECORE_CON_SSL_ERROR_NONE;
951      }
952    if (!(cl->ssl = SSL_new(cl->ssl_ctx)))
953      {
954         SSL_CTX_free(cl->ssl_ctx);
955         return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
956      }
957
958    if ((client_cert) && (client_cert->cert) && (private_key->key) &&
959        ((cl->server->type & ECORE_CON_TYPE) & ECORE_CON_LOAD_CERT))
960      {
961         //FIXME: just log and go on without cert if loading fails?
962         if (!SSL_CTX_use_certificate(cl->server->ssl_ctx, client_cert->cert) ||
963             !SSL_CTX_use_PrivateKey(cl->server->ssl_ctx, private_key->key) ||
964             !SSL_CTX_check_private_key(cl->server->ssl_ctx))
965            ERR(
966               "ssl cert load failed: %s", ERR_reason_error_string(ERR_get_error()));
967
968         client_cert->count++;
969         private_key->count++;
970      }
971
972    SSL_set_fd(cl->ssl, cl->fd);
973
974    return ECORE_CON_SSL_ERROR_NONE;
975 }
976
977
978 static Eina_Bool
979 _ecore_con_ssl_client_cert_add_openssl(const char *cert_file,
980                                        const char *crl_file,
981                                        const char *key_file)
982 {
983    FILE *fp = NULL;
984    EVP_PKEY *privkey = NULL;
985    X509 *cert = NULL;
986
987    if (!(fp = fopen(cert_file, "r")))
988       goto on_error;
989
990    if (!(cert = PEM_read_X509(fp, NULL, NULL, NULL)))
991       goto on_error;
992
993    if (key_file)
994      {
995         fclose(fp);
996         if (!(fp = fopen(key_file, "r")))
997            goto on_error;
998      }
999
1000    if (!(privkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL)))
1001       goto on_error;
1002
1003         fclose(fp);
1004
1005    if (!client_cert)
1006      {
1007         client_cert = malloc(sizeof(openssl));
1008            if (!client_cert)
1009            return EINA_FALSE;
1010      }
1011    else if ((client_cert->cert) && (--client_cert->count < 1))
1012       X509_free(client_cert->cert);
1013
1014    if (!private_key)
1015      {
1016         private_key = malloc(sizeof(openssl_pkey));
1017            if (!private_key) return EINA_FALSE;
1018      }
1019    else if ((private_key->key) && ((--private_key->count) < 1))
1020       EVP_PKEY_free(private_key->key);
1021
1022    private_key->key = privkey;
1023    client_cert->cert = cert;
1024
1025    private_key->count = client_cert->count = 1;
1026
1027    return EINA_TRUE;
1028
1029 on_error:
1030    if (fp)
1031       fclose(fp);
1032
1033    if (cert)
1034       X509_free(cert);
1035
1036    if (privkey)
1037       EVP_PKEY_free(privkey);
1038
1039    return EINA_FALSE;
1040 }
1041
1042 static Ecore_Con_Ssl_Error
1043 _ecore_con_ssl_client_shutdown_openssl(Ecore_Con_Client *cl)
1044 {
1045    if (cl->ssl)
1046      {
1047         if (!SSL_shutdown(cl->ssl))
1048            SSL_shutdown(cl->ssl);
1049
1050         SSL_free(cl->ssl);
1051      }
1052
1053    if (cl->ssl_ctx)
1054      {
1055         SSL_CTX_free(cl->ssl_ctx);
1056         if (((cl->server->type & ECORE_CON_TYPE) & ECORE_CON_LOAD_CERT) &&
1057             (client_cert) && (client_cert->cert) && (--client_cert->count < 1))
1058           {
1059              X509_free(client_cert->cert);
1060              free(client_cert);
1061              client_cert = NULL;
1062           }
1063
1064         if (((cl->server->type & ECORE_CON_TYPE) & ECORE_CON_LOAD_CERT) &&
1065             (private_key) && (private_key->key) && (--private_key->count < 1))
1066           {
1067              EVP_PKEY_free(private_key->key);
1068              free(private_key);
1069              private_key = NULL;
1070           }
1071      }
1072
1073    _ecore_con_ssl_client_prepare_openssl(cl);
1074
1075    return ECORE_CON_SSL_ERROR_NONE;
1076 }
1077
1078 static int
1079 _ecore_con_ssl_client_read_openssl(Ecore_Con_Client *cl, unsigned char *buf,
1080                                    int size)
1081 {
1082    int num;
1083
1084    num = SSL_read(cl->ssl, buf, size);
1085    cl->ssl_err = SSL_get_error(cl->ssl, num);
1086
1087    if (cl->fd_handler)
1088      {
1089         if (cl->ssl && cl->ssl_err ==
1090             SSL_ERROR_WANT_READ)
1091            ecore_main_fd_handler_active_set(cl->fd_handler,
1092                                             ECORE_FD_READ);
1093         else if (cl->ssl && cl->ssl_err ==
1094                  SSL_ERROR_WANT_WRITE)
1095            ecore_main_fd_handler_active_set(
1096               cl->fd_handler,
1097               ECORE_FD_WRITE);
1098      }
1099
1100    if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
1101        (cl->ssl_err == SSL_ERROR_SYSCALL) ||
1102        (cl->ssl_err == SSL_ERROR_SSL))
1103       return -1;
1104
1105    if (num < 0)
1106       return 0;
1107
1108    return num;
1109 }
1110
1111 static int
1112 _ecore_con_ssl_client_write_openssl(Ecore_Con_Client *cl, unsigned char *buf,
1113                                     int size)
1114 {
1115    int num;
1116
1117    num = SSL_write(cl->ssl, buf, size);
1118    cl->ssl_err = SSL_get_error(cl->ssl, num);
1119
1120    if (cl->fd_handler)
1121      {
1122         if (cl->ssl && cl->ssl_err ==
1123             SSL_ERROR_WANT_READ)
1124            ecore_main_fd_handler_active_set(cl->fd_handler,
1125                                             ECORE_FD_READ);
1126         else if (cl->ssl && cl->ssl_err ==
1127                  SSL_ERROR_WANT_WRITE)
1128            ecore_main_fd_handler_active_set(
1129               cl->fd_handler,
1130               ECORE_FD_WRITE);
1131      }
1132
1133    if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
1134        (cl->ssl_err == SSL_ERROR_SYSCALL) ||
1135        (cl->ssl_err == SSL_ERROR_SSL))
1136       return -1;
1137
1138    if (num < 0)
1139       return 0;
1140
1141    return num;
1142 }
1143
1144 #else
1145
1146 /*
1147  * No Ssl
1148  */
1149
1150 static Ecore_Con_Ssl_Error
1151 _ecore_con_ssl_init_none(void)
1152 {
1153    return ECORE_CON_SSL_ERROR_NONE;
1154 }
1155
1156 static Ecore_Con_Ssl_Error
1157 _ecore_con_ssl_shutdown_none(void)
1158 {
1159    return ECORE_CON_SSL_ERROR_NONE;
1160 }
1161
1162 static void
1163 _ecore_con_ssl_server_prepare_none(Ecore_Con_Server *svr)
1164 {
1165 }
1166
1167 static Ecore_Con_Ssl_Error
1168 _ecore_con_ssl_server_init_none(Ecore_Con_Server *svr)
1169 {
1170    return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
1171 }
1172
1173 static Eina_Bool
1174 _ecore_con_ssl_server_cert_add_none(const char *cert_file)
1175 {
1176    return EINA_TRUE;
1177 }
1178
1179 static Ecore_Con_Ssl_Error
1180 _ecore_con_ssl_server_shutdown_none(Ecore_Con_Server *svr)
1181 {
1182    return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
1183 }
1184
1185 /* Tries to connect an Ecore_Con_Server to an SSL host.
1186  * Returns 1 on success, -1 on fatal errors and 0 if the caller
1187  * should try again later.
1188  */
1189 static Ecore_Con_State
1190 _ecore_con_ssl_server_try_none(Ecore_Con_Server *svr)
1191 {
1192    return ECORE_CON_DISCONNECTED;
1193 }
1194
1195 static int
1196 _ecore_con_ssl_server_read_none(Ecore_Con_Server *svr, unsigned char *buf,
1197                                 int size)
1198 {
1199    return -1;
1200 }
1201
1202 static int
1203 _ecore_con_ssl_server_write_none(Ecore_Con_Server *svr, unsigned char *buf,
1204                                  int size)
1205 {
1206    return -1;
1207 }
1208
1209 static void
1210 _ecore_con_ssl_client_prepare_none(Ecore_Con_Client *cl)
1211 {
1212    return;
1213 }
1214
1215 static Ecore_Con_Ssl_Error
1216 _ecore_con_ssl_client_init_none(Ecore_Con_Client *cl)
1217 {
1218    return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
1219 }
1220
1221 static Eina_Bool
1222 _ecore_con_ssl_client_cert_add_none(const char *cert_file,
1223                                     const char *crl_file,
1224                                     const char *key_file)
1225 {
1226    return EINA_TRUE;
1227 }
1228
1229 static Ecore_Con_Ssl_Error
1230 _ecore_con_ssl_client_shutdown_none(Ecore_Con_Client *cl)
1231 {
1232    return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
1233 }
1234
1235 static int
1236 _ecore_con_ssl_client_read_none(Ecore_Con_Client *cl, unsigned char *buf,
1237                                 int size)
1238 {
1239    return -1;
1240 }
1241
1242 static int
1243 _ecore_con_ssl_client_write_none(Ecore_Con_Client *cl, unsigned char *buf,
1244                                  int size)
1245 {
1246    return -1;
1247 }
1248
1249 #endif