2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
10 # include <gnutls/gnutls.h>
12 # include <openssl/ssl.h>
15 #ifdef HAVE_WS2TCPIP_H
16 # include <ws2tcpip.h>
20 #include "ecore_con_private.h"
22 static int _init_con_ssl_init_count = 0;
25 static int _client_connected = 0;
27 # define SSL_SUFFIX(ssl_func) ssl_func##_gnutls
28 # define _ECORE_CON_SSL_AVAILABLE 1
31 # define SSL_SUFFIX(ssl_func) ssl_func##_openssl
32 # define _ECORE_CON_SSL_AVAILABLE 2
35 # define SSL_SUFFIX(ssl_func) ssl_func##_none
36 # define _ECORE_CON_SSL_AVAILABLE 0
40 static Ecore_Con_Ssl_Error
41 SSL_SUFFIX(_ecore_con_ssl_init)(void);
42 static Ecore_Con_Ssl_Error
43 SSL_SUFFIX(_ecore_con_ssl_shutdown)(void);
46 SSL_SUFFIX(_ecore_con_ssl_server_prepare)(Ecore_Con_Server *svr);
47 static Ecore_Con_Ssl_Error
48 SSL_SUFFIX(_ecore_con_ssl_server_init)(Ecore_Con_Server *svr);
49 static Ecore_Con_Ssl_Error
50 SSL_SUFFIX(_ecore_con_ssl_server_shutdown)(Ecore_Con_Server *svr);
51 static Ecore_Con_State
52 SSL_SUFFIX(_ecore_con_ssl_server_try)(Ecore_Con_Server *svr);
54 SSL_SUFFIX(_ecore_con_ssl_server_read)(Ecore_Con_Server *svr, unsigned char *buf, int size);
56 SSL_SUFFIX(_ecore_con_ssl_server_write)(Ecore_Con_Server *svr, unsigned char *buf, int size);
59 SSL_SUFFIX(_ecore_con_ssl_client_prepare)(Ecore_Con_Client *cl);
60 static Ecore_Con_Ssl_Error
61 SSL_SUFFIX(_ecore_con_ssl_client_init)(Ecore_Con_Client *cl);
62 static Ecore_Con_Ssl_Error
63 SSL_SUFFIX(_ecore_con_ssl_client_shutdown)(Ecore_Con_Client *cl);
65 SSL_SUFFIX(_ecore_con_ssl_client_read)(Ecore_Con_Client *cl, unsigned char *buf, int size);
67 SSL_SUFFIX(_ecore_con_ssl_client_write)(Ecore_Con_Client *cl, unsigned char *buf, int size);
74 ecore_con_ssl_init(void)
76 if (!_init_con_ssl_init_count++)
77 SSL_SUFFIX(_ecore_con_ssl_init)();
79 return _init_con_ssl_init_count;
83 ecore_con_ssl_shutdown(void)
85 if (!--_init_con_ssl_init_count)
86 SSL_SUFFIX(_ecore_con_ssl_shutdown)();
88 return _init_con_ssl_init_count;
92 * Returns if SSL support is available
93 * @return 1 if SSL is available, 0 if it is not.
94 * @ingroup Ecore_Con_Client_Group
97 ecore_con_ssl_available_get(void)
99 return _ECORE_CON_SSL_AVAILABLE;
104 ecore_con_ssl_server_prepare(Ecore_Con_Server *svr)
106 SSL_SUFFIX(_ecore_con_ssl_server_prepare)(svr);
110 ecore_con_ssl_server_init(Ecore_Con_Server *svr)
112 return SSL_SUFFIX(_ecore_con_ssl_server_init)(svr);
116 ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr)
118 return SSL_SUFFIX(_ecore_con_ssl_server_shutdown)(svr);
122 ecore_con_ssl_server_try(Ecore_Con_Server *svr)
124 return SSL_SUFFIX(_ecore_con_ssl_server_try)(svr);
128 ecore_con_ssl_server_read(Ecore_Con_Server *svr, unsigned char *buf, int size)
130 return SSL_SUFFIX(_ecore_con_ssl_server_read)(svr, buf, size);
134 ecore_con_ssl_server_write(Ecore_Con_Server *svr, unsigned char *buf, int size)
136 return SSL_SUFFIX(_ecore_con_ssl_server_write)(svr, buf, size);
140 ecore_con_ssl_client_init(Ecore_Con_Client *cl)
142 return SSL_SUFFIX(_ecore_con_ssl_client_init)(cl);
146 ecore_con_ssl_client_shutdown(Ecore_Con_Client *cl)
148 return SSL_SUFFIX(_ecore_con_ssl_client_shutdown)(cl);
152 ecore_con_ssl_client_read(Ecore_Con_Client *cl, unsigned char *buf, int size)
154 return SSL_SUFFIX(_ecore_con_ssl_client_read)(cl, buf, size);
158 ecore_con_ssl_client_write(Ecore_Con_Client *cl, unsigned char *buf, int size)
160 return SSL_SUFFIX(_ecore_con_ssl_client_write)(cl, buf, size);
169 static Ecore_Con_Ssl_Error
170 _ecore_con_ssl_init_gnutls(void)
172 if (gnutls_global_init())
173 return ECORE_CON_SSL_ERROR_INIT_FAILED;
175 return ECORE_CON_SSL_ERROR_NONE;
178 static Ecore_Con_Ssl_Error
179 _ecore_con_ssl_shutdown_gnutls(void)
181 gnutls_global_deinit();
183 return ECORE_CON_SSL_ERROR_NONE;
187 _ecore_con_ssl_server_prepare_gnutls(Ecore_Con_Server *svr)
190 svr->anoncred_c = NULL;
194 static Ecore_Con_Ssl_Error
195 _ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr)
197 const int *proto = NULL;
199 const int kx[] = { GNUTLS_KX_ANON_DH, 0 };
200 const int ssl3_proto[] = { GNUTLS_SSL3, 0 };
201 const int tls_proto[] = {
210 switch (svr->type & ECORE_CON_SSL)
212 case ECORE_CON_USE_SSL2: /* not supported because of security issues */
213 return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
214 case ECORE_CON_USE_SSL3:
217 case ECORE_CON_USE_TLS:
221 return ECORE_CON_SSL_ERROR_NONE;
224 gnutls_anon_allocate_client_credentials(&(svr->anoncred_c));
225 gnutls_init(&(svr->session), GNUTLS_CLIENT);
226 gnutls_set_default_priority(svr->session);
227 gnutls_kx_set_priority(svr->session, kx);
228 gnutls_credentials_set(svr->session, GNUTLS_CRD_ANON, svr->anoncred_c);
229 gnutls_kx_set_priority(svr->session, kx);
230 gnutls_protocol_set_priority(svr->session, proto);
231 gnutls_dh_set_prime_bits(svr->session, 512);
233 gnutls_transport_set_ptr(svr->session, (gnutls_transport_ptr_t)svr->fd);
235 while ((ret = gnutls_handshake(svr->session)) < 0)
237 if ((ret == GNUTLS_E_AGAIN) ||
238 (ret == GNUTLS_E_INTERRUPTED))
241 _ecore_con_ssl_server_shutdown_gnutls(svr);
242 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
245 return ECORE_CON_SSL_ERROR_NONE;
248 static Ecore_Con_Ssl_Error
249 _ecore_con_ssl_server_shutdown_gnutls(Ecore_Con_Server *svr)
253 gnutls_bye(svr->session, GNUTLS_SHUT_RDWR);
254 gnutls_deinit(svr->session);
257 gnutls_anon_free_client_credentials(svr->anoncred_c);
258 _ecore_con_ssl_server_prepare_gnutls(svr);
260 return ECORE_CON_SSL_ERROR_NONE;
263 /* Tries to connect an Ecore_Con_Server to an SSL host.
264 * Returns 1 on success, -1 on fatal errors and 0 if the caller
265 * should try again later.
267 static Ecore_Con_State
268 _ecore_con_ssl_server_try_gnutls(Ecore_Con_Server *svr __UNUSED__)
270 return ECORE_CON_CONNECTED;
274 _ecore_con_ssl_server_read_gnutls(Ecore_Con_Server *svr, unsigned char *buf, int size)
278 num = gnutls_record_recv(svr->session, buf, size);
281 if ((num == GNUTLS_E_AGAIN) ||
282 (num == GNUTLS_E_REHANDSHAKE) ||
283 (num == GNUTLS_E_INTERRUPTED))
289 _ecore_con_ssl_server_write_gnutls(Ecore_Con_Server *svr, unsigned char *buf, int size)
293 num = gnutls_record_send(svr->session, buf, size);
296 if ((num == GNUTLS_E_AGAIN) ||
297 (num == GNUTLS_E_REHANDSHAKE) ||
298 (num == GNUTLS_E_INTERRUPTED))
304 _ecore_con_ssl_client_prepare_gnutls(Ecore_Con_Client *cl)
307 if (!_client_connected)
308 cl->server->anoncred_s = NULL;
311 static Ecore_Con_Ssl_Error
312 _ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
314 const int *proto = NULL;
315 gnutls_dh_params_t dh_params;
317 const int kx[] = { GNUTLS_KX_ANON_DH, 0 };
318 const int ssl3_proto[] = { GNUTLS_SSL3, 0 };
319 const int tls_proto[] = {
328 switch (cl->server->type & ECORE_CON_SSL)
330 case ECORE_CON_USE_SSL2: /* not supported because of security issues */
331 return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
332 case ECORE_CON_USE_SSL3:
335 case ECORE_CON_USE_TLS:
339 return ECORE_CON_SSL_ERROR_NONE;
343 if (!cl->server->anoncred_s)
345 gnutls_anon_allocate_server_credentials(&(cl->server->anoncred_s));
346 gnutls_dh_params_init(&dh_params);
347 gnutls_dh_params_generate2(dh_params, 512);
348 gnutls_anon_set_server_dh_params(cl->server->anoncred_s, dh_params);
351 gnutls_init(&(cl->session), GNUTLS_SERVER);
352 gnutls_set_default_priority(cl->session);
353 gnutls_credentials_set(cl->session, GNUTLS_CRD_ANON, cl->server->anoncred_s);
355 gnutls_kx_set_priority(cl->session, kx);
357 gnutls_protocol_set_priority(cl->session, proto);
359 gnutls_dh_set_prime_bits(cl->session, 512);
361 gnutls_transport_set_ptr(cl->session, (gnutls_transport_ptr_t)cl->fd);
363 while ((ret = gnutls_handshake(cl->session)) < 0)
365 if ((ret == GNUTLS_E_AGAIN) ||
366 (ret == GNUTLS_E_INTERRUPTED))
369 _ecore_con_ssl_client_shutdown_gnutls(cl);
370 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
373 return ECORE_CON_SSL_ERROR_NONE;
376 static Ecore_Con_Ssl_Error
377 _ecore_con_ssl_client_shutdown_gnutls(Ecore_Con_Client *cl)
381 gnutls_bye(cl->session, GNUTLS_SHUT_RDWR);
382 gnutls_deinit(cl->session);
384 if (cl->server->anoncred_s && !--_client_connected)
385 gnutls_anon_free_server_credentials(cl->server->anoncred_s);
386 _ecore_con_ssl_client_prepare_gnutls(cl);
388 return ECORE_CON_SSL_ERROR_NONE;
392 _ecore_con_ssl_client_read_gnutls(Ecore_Con_Client *cl, unsigned char *buf, int size)
396 num = gnutls_record_recv(cl->session, buf, size);
399 if ((num == GNUTLS_E_AGAIN) ||
400 (num == GNUTLS_E_REHANDSHAKE) ||
401 (num == GNUTLS_E_INTERRUPTED))
407 _ecore_con_ssl_client_write_gnutls(Ecore_Con_Client *cl, unsigned char *buf, int size)
411 num = gnutls_record_send(cl->session, buf, size);
414 if ((num == GNUTLS_E_AGAIN) ||
415 (num == GNUTLS_E_REHANDSHAKE) ||
416 (num == GNUTLS_E_INTERRUPTED))
427 static Ecore_Con_Ssl_Error
428 _ecore_con_ssl_init_openssl(void)
431 SSL_load_error_strings();
433 return ECORE_CON_SSL_ERROR_NONE;
436 static Ecore_Con_Ssl_Error
437 _ecore_con_ssl_shutdown_openssl(void)
439 // FIXME nothing to do ?
440 return ECORE_CON_SSL_ERROR_NONE;
444 _ecore_con_ssl_server_prepare_openssl(Ecore_Con_Server *svr)
448 svr->ssl_err = SSL_ERROR_NONE;
451 static Ecore_Con_Ssl_Error
452 _ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr)
454 switch (svr->type & ECORE_CON_SSL)
456 case ECORE_CON_USE_SSL2:
457 /* Unsafe version of SSL */
458 if (!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
459 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
461 case ECORE_CON_USE_SSL3:
462 if (!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())))
463 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
465 case ECORE_CON_USE_TLS:
466 if (!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())))
467 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
470 return ECORE_CON_SSL_ERROR_NONE;
472 if (!(svr->ssl = SSL_new(svr->ssl_ctx)))
474 SSL_CTX_free(svr->ssl_ctx);
475 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
478 SSL_set_fd(svr->ssl, svr->fd);
480 return ECORE_CON_SSL_ERROR_NONE;
483 static Ecore_Con_Ssl_Error
484 _ecore_con_ssl_server_shutdown_openssl(Ecore_Con_Server *svr)
488 if (!SSL_shutdown(svr->ssl))
489 SSL_shutdown(svr->ssl);
492 if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx);
494 _ecore_con_ssl_server_prepare_openssl(svr);
496 return ECORE_CON_SSL_ERROR_NONE;
499 /* Tries to connect an Ecore_Con_Server to an SSL host.
500 * Returns 1 on success, -1 on fatal errors and 0 if the caller
501 * should try again later.
503 static Ecore_Con_State
504 _ecore_con_ssl_server_try_openssl(Ecore_Con_Server *svr)
508 if ((res = SSL_connect(svr->ssl)) == 1)
509 return ECORE_CON_CONNECTED;
511 svr->ssl_err = SSL_get_error(svr->ssl, res);
513 switch (svr->ssl_err)
516 return ECORE_CON_CONNECTED;
517 case SSL_ERROR_WANT_READ:
518 flag = ECORE_FD_READ;
520 case SSL_ERROR_WANT_WRITE:
521 flag = ECORE_FD_WRITE;
524 return ECORE_CON_DISCONNECTED;
527 if (svr->fd_handler && flag)
528 ecore_main_fd_handler_active_set(svr->fd_handler, flag);
530 return ECORE_CON_INPROGRESS;
534 _ecore_con_ssl_server_read_openssl(Ecore_Con_Server *svr, unsigned char *buf, int size)
538 num = SSL_read(svr->ssl, buf, size);
539 svr->ssl_err = SSL_get_error(svr->ssl, num);
543 if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ)
544 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
545 else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE)
546 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
549 if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
550 (svr->ssl_err == SSL_ERROR_SYSCALL) ||
551 (svr->ssl_err == SSL_ERROR_SSL))
559 _ecore_con_ssl_server_write_openssl(Ecore_Con_Server *svr, unsigned char *buf, int size)
563 num = SSL_write(svr->ssl, buf, size);
564 svr->ssl_err = SSL_get_error(svr->ssl, num);
568 if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ)
569 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
570 else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE)
571 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
574 if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
575 (svr->ssl_err == SSL_ERROR_SYSCALL) ||
576 (svr->ssl_err == SSL_ERROR_SSL))
584 _ecore_con_ssl_client_prepare_openssl(Ecore_Con_Client *cl)
588 cl->ssl_err = SSL_ERROR_NONE;
591 static Ecore_Con_Ssl_Error
592 _ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl)
594 switch (cl->server->type & ECORE_CON_SSL)
596 case ECORE_CON_USE_SSL2:
597 /* Unsafe version of SSL */
598 if (!(cl->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
599 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
601 case ECORE_CON_USE_SSL3:
602 if (!(cl->ssl_ctx = SSL_CTX_new(SSLv3_client_method())))
603 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
605 case ECORE_CON_USE_TLS:
606 if (!(cl->ssl_ctx = SSL_CTX_new(TLSv1_client_method())))
607 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
610 return ECORE_CON_SSL_ERROR_NONE;
612 if (!(cl->ssl = SSL_new(cl->ssl_ctx)))
614 SSL_CTX_free(cl->ssl_ctx);
615 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
618 SSL_set_fd(cl->ssl, cl->fd);
620 return ECORE_CON_SSL_ERROR_NONE;
623 static Ecore_Con_Ssl_Error
624 _ecore_con_ssl_client_shutdown_openssl(Ecore_Con_Client *cl)
628 if (!SSL_shutdown(cl->ssl))
629 SSL_shutdown(cl->ssl);
632 if (cl->ssl_ctx) SSL_CTX_free(cl->ssl_ctx);
634 _ecore_con_ssl_client_prepare_openssl(cl);
636 return ECORE_CON_SSL_ERROR_NONE;
640 _ecore_con_ssl_client_read_openssl(Ecore_Con_Client *cl, unsigned char *buf, int size)
644 num = SSL_read(cl->ssl, buf, size);
645 cl->ssl_err = SSL_get_error(cl->ssl, num);
649 if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ)
650 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
651 else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE)
652 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
655 if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
656 (cl->ssl_err == SSL_ERROR_SYSCALL) ||
657 (cl->ssl_err == SSL_ERROR_SSL))
665 _ecore_con_ssl_client_write_openssl(Ecore_Con_Client *cl, unsigned char *buf, int size)
669 num = SSL_write(cl->ssl, buf, size);
670 cl->ssl_err = SSL_get_error(cl->ssl, num);
674 if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ)
675 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
676 else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE)
677 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
680 if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
681 (cl->ssl_err == SSL_ERROR_SYSCALL) ||
682 (cl->ssl_err == SSL_ERROR_SSL))
695 static Ecore_Con_Ssl_Error
696 _ecore_con_ssl_init_none(void)
698 return ECORE_CON_SSL_ERROR_NONE;
701 static Ecore_Con_Ssl_Error
702 _ecore_con_ssl_shutdown_none(void)
704 return ECORE_CON_SSL_ERROR_NONE;
708 _ecore_con_ssl_server_prepare_none(Ecore_Con_Server *svr)
712 static Ecore_Con_Ssl_Error
713 _ecore_con_ssl_server_init_none(Ecore_Con_Server *svr)
715 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
718 static Ecore_Con_Ssl_Error
719 _ecore_con_ssl_server_shutdown_none(Ecore_Con_Server *svr)
721 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
724 /* Tries to connect an Ecore_Con_Server to an SSL host.
725 * Returns 1 on success, -1 on fatal errors and 0 if the caller
726 * should try again later.
728 static Ecore_Con_State
729 _ecore_con_ssl_server_try_none(Ecore_Con_Server *svr)
731 return ECORE_CON_DISCONNECTED;
735 _ecore_con_ssl_server_read_none(Ecore_Con_Server *svr, unsigned char *buf, int size)
741 _ecore_con_ssl_server_write_none(Ecore_Con_Server *svr, unsigned char *buf, int size)
747 _ecore_con_ssl_client_prepare_none(Ecore_Con_Client *cl)
752 static Ecore_Con_Ssl_Error
753 _ecore_con_ssl_client_init_none(Ecore_Con_Client *cl)
755 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
758 static Ecore_Con_Ssl_Error
759 _ecore_con_ssl_client_shutdown_none(Ecore_Con_Client *cl)
761 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
765 _ecore_con_ssl_client_read_none(Ecore_Con_Client *cl, unsigned char *buf, int size)
771 _ecore_con_ssl_client_write_none(Ecore_Con_Client *cl, unsigned char *buf, int size)