aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 17:29:19 +1000
committerDavid Walter Seikel2013-01-13 17:29:19 +1000
commit07274513e984f0b5544586c74508ccd16e7dcafa (patch)
treeb32ff2a9136fbc1a4a6a0ed1e4d79cde0f5f16d9 /libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c
parentAdded Irrlicht 1.8, but without all the Windows binaries. (diff)
downloadSledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.zip
SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.gz
SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.bz2
SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.xz
Remove EFL, since it's been released now.
Diffstat (limited to 'libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c')
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c2113
1 files changed, 0 insertions, 2113 deletions
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c b/libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c
deleted file mode 100644
index cd8b9c6..0000000
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c
+++ /dev/null
@@ -1,2113 +0,0 @@
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 <sys/stat.h>
20#include "Ecore.h"
21#include "ecore_con_private.h"
22
23EAPI int ECORE_CON_EVENT_CLIENT_UPGRADE = 0;
24EAPI int ECORE_CON_EVENT_SERVER_UPGRADE = 0;
25
26static int _init_con_ssl_init_count = 0;
27
28#ifdef USE_GNUTLS
29# ifdef EINA_HAVE_THREADS
30GCRY_THREAD_OPTION_PTHREAD_IMPL;
31# endif
32
33static int _client_connected = 0;
34
35# define SSL_SUFFIX(ssl_func) ssl_func ## _gnutls
36# define _ECORE_CON_SSL_AVAILABLE 1
37
38#elif USE_OPENSSL
39
40# define SSL_SUFFIX(ssl_func) ssl_func ## _openssl
41# define _ECORE_CON_SSL_AVAILABLE 2
42
43#else
44# define SSL_SUFFIX(ssl_func) ssl_func ## _none
45# define _ECORE_CON_SSL_AVAILABLE 0
46
47#endif
48
49#if USE_GNUTLS
50static void
51_gnutls_print_errors(void *conn, int type, int ret)
52{
53 char buf[1024];
54
55 if (!ret) return;
56
57 snprintf(buf, sizeof(buf), "GNUTLS error: %s - %s", gnutls_strerror_name(ret), gnutls_strerror(ret));
58 if (type == ECORE_CON_EVENT_CLIENT_ERROR)
59 ecore_con_event_client_error(conn, buf);
60 else
61 ecore_con_event_server_error(conn, buf);
62}
63
64static void
65_gnutls_print_session(const gnutls_datum_t *cert_list, unsigned int cert_list_size)
66{
67 char *c = NULL;
68 gnutls_x509_crt_t crt;
69 unsigned int x;
70
71 if (!eina_log_domain_level_check(_ecore_con_log_dom, EINA_LOG_LEVEL_DBG)) return;
72 for (x = 0; x < cert_list_size; x++)
73 {
74 gnutls_x509_crt_init(&crt);
75 gnutls_x509_crt_import(crt, &cert_list[x], GNUTLS_X509_FMT_DER);
76 gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_FULL, (gnutls_datum_t*)&c);
77 INF("CERTIFICATE:\n%s", c);
78 gnutls_free(c);
79 gnutls_x509_crt_deinit(crt);
80 crt = NULL;
81 }
82}
83
84#ifdef ISCOMFITOR
85static void
86_gnutls_log_func(int level,
87 const char *str)
88{
89 char buf[128];
90 strncat(buf, str, strlen(str) - 1);
91 DBG("|<%d>| %s", level, buf);
92}
93#endif
94
95static const char *
96SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_description_t status)
97{
98 switch (status)
99 {
100 case GNUTLS_HANDSHAKE_HELLO_REQUEST:
101 return "Hello request";
102
103 case GNUTLS_HANDSHAKE_CLIENT_HELLO:
104 return "Client hello";
105
106 case GNUTLS_HANDSHAKE_SERVER_HELLO:
107 return "Server hello";
108
109 case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET:
110 return "New session ticket";
111
112 case GNUTLS_HANDSHAKE_CERTIFICATE_PKT:
113 return "Certificate packet";
114
115 case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE:
116 return "Server key exchange";
117
118 case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST:
119 return "Certificate request";
120
121 case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE:
122 return "Server hello done";
123
124 case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY:
125 return "Certificate verify";
126
127 case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
128 return "Client key exchange";
129
130 case GNUTLS_HANDSHAKE_FINISHED:
131 return "Finished";
132
133 case GNUTLS_HANDSHAKE_SUPPLEMENTAL:
134 return "Supplemental";
135 }
136 return NULL;
137}
138
139#elif USE_OPENSSL
140
141static void
142_openssl_print_verify_error(int error)
143{
144 switch (error)
145 {
146#define ERROR(X) \
147 case (X): \
148 ERR("%s", #X); \
149 break
150#ifdef X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT
151 ERROR(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT);
152#endif
153#ifdef X509_V_ERR_UNABLE_TO_GET_CRL
154 ERROR(X509_V_ERR_UNABLE_TO_GET_CRL);
155#endif
156#ifdef X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE
157 ERROR(X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE);
158#endif
159#ifdef X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE
160 ERROR(X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE);
161#endif
162#ifdef X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY
163 ERROR(X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY);
164#endif
165#ifdef X509_V_ERR_CERT_SIGNATURE_FAILURE
166 ERROR(X509_V_ERR_CERT_SIGNATURE_FAILURE);
167#endif
168#ifdef X509_V_ERR_CRL_SIGNATURE_FAILURE
169 ERROR(X509_V_ERR_CRL_SIGNATURE_FAILURE);
170#endif
171#ifdef X509_V_ERR_CERT_NOT_YET_VALID
172 ERROR(X509_V_ERR_CERT_NOT_YET_VALID);
173#endif
174#ifdef X509_V_ERR_CERT_HAS_EXPIRED
175 ERROR(X509_V_ERR_CERT_HAS_EXPIRED);
176#endif
177#ifdef X509_V_ERR_CRL_NOT_YET_VALID
178 ERROR(X509_V_ERR_CRL_NOT_YET_VALID);
179#endif
180#ifdef X509_V_ERR_CRL_HAS_EXPIRED
181 ERROR(X509_V_ERR_CRL_HAS_EXPIRED);
182#endif
183#ifdef X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
184 ERROR(X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD);
185#endif
186#ifdef X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
187 ERROR(X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD);
188#endif
189#ifdef X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
190 ERROR(X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD);
191#endif
192#ifdef X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
193 ERROR(X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
194#endif
195#ifdef X509_V_ERR_OUT_OF_MEM
196 ERROR(X509_V_ERR_OUT_OF_MEM);
197#endif
198#ifdef X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
199 ERROR(X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT);
200#endif
201#ifdef X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
202 ERROR(X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN);
203#endif
204#ifdef X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
205 ERROR(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY);
206#endif
207#ifdef X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
208 ERROR(X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE);
209#endif
210#ifdef X509_V_ERR_CERT_CHAIN_TOO_LONG
211 ERROR(X509_V_ERR_CERT_CHAIN_TOO_LONG);
212#endif
213#ifdef X509_V_ERR_CERT_REVOKED
214 ERROR(X509_V_ERR_CERT_REVOKED);
215#endif
216#ifdef X509_V_ERR_INVALID_CA
217 ERROR(X509_V_ERR_INVALID_CA);
218#endif
219#ifdef X509_V_ERR_PATH_LENGTH_EXCEEDED
220 ERROR(X509_V_ERR_PATH_LENGTH_EXCEEDED);
221#endif
222#ifdef X509_V_ERR_INVALID_PURPOSE
223 ERROR(X509_V_ERR_INVALID_PURPOSE);
224#endif
225#ifdef X509_V_ERR_CERT_UNTRUSTED
226 ERROR(X509_V_ERR_CERT_UNTRUSTED);
227#endif
228#ifdef X509_V_ERR_CERT_REJECTED
229 ERROR(X509_V_ERR_CERT_REJECTED);
230#endif
231 /* These are 'informational' when looking for issuer cert */
232#ifdef X509_V_ERR_SUBJECT_ISSUER_MISMATCH
233 ERROR(X509_V_ERR_SUBJECT_ISSUER_MISMATCH);
234#endif
235#ifdef X509_V_ERR_AKID_SKID_MISMATCH
236 ERROR(X509_V_ERR_AKID_SKID_MISMATCH);
237#endif
238#ifdef X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH
239 ERROR(X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH);
240#endif
241#ifdef X509_V_ERR_KEYUSAGE_NO_CERTSIGN
242 ERROR(X509_V_ERR_KEYUSAGE_NO_CERTSIGN);
243#endif
244
245#ifdef X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER
246 ERROR(X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER);
247#endif
248#ifdef X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION
249 ERROR(X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION);
250#endif
251#ifdef X509_V_ERR_KEYUSAGE_NO_CRL_SIGN
252 ERROR(X509_V_ERR_KEYUSAGE_NO_CRL_SIGN);
253#endif
254#ifdef X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION
255 ERROR(X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION);
256#endif
257#ifdef X509_V_ERR_INVALID_NON_CA
258 ERROR(X509_V_ERR_INVALID_NON_CA);
259#endif
260#ifdef X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED
261 ERROR(X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED);
262#endif
263#ifdef X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE
264 ERROR(X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE);
265#endif
266#ifdef X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED
267 ERROR(X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED);
268#endif
269
270#ifdef X509_V_ERR_INVALID_EXTENSION
271 ERROR(X509_V_ERR_INVALID_EXTENSION);
272#endif
273#ifdef X509_V_ERR_INVALID_POLICY_EXTENSION
274 ERROR(X509_V_ERR_INVALID_POLICY_EXTENSION);
275#endif
276#ifdef X509_V_ERR_NO_EXPLICIT_POLICY
277 ERROR(X509_V_ERR_NO_EXPLICIT_POLICY);
278#endif
279#ifdef X509_V_ERR_DIFFERENT_CRL_SCOPE
280 ERROR(X509_V_ERR_DIFFERENT_CRL_SCOPE);
281#endif
282#ifdef X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE
283 ERROR(X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE);
284#endif
285
286#ifdef X509_V_ERR_UNNESTED_RESOURCE
287 ERROR(X509_V_ERR_UNNESTED_RESOURCE);
288#endif
289
290#ifdef X509_V_ERR_PERMITTED_VIOLATION
291 ERROR(X509_V_ERR_PERMITTED_VIOLATION);
292#endif
293#ifdef X509_V_ERR_EXCLUDED_VIOLATION
294 ERROR(X509_V_ERR_EXCLUDED_VIOLATION);
295#endif
296#ifdef X509_V_ERR_SUBTREE_MINMAX
297 ERROR(X509_V_ERR_SUBTREE_MINMAX);
298#endif
299#ifdef X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE
300 ERROR(X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE);
301#endif
302#ifdef X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX
303 ERROR(X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX);
304#endif
305#ifdef X509_V_ERR_UNSUPPORTED_NAME_SYNTAX
306 ERROR(X509_V_ERR_UNSUPPORTED_NAME_SYNTAX);
307#endif
308#ifdef X509_V_ERR_CRL_PATH_VALIDATION_ERROR
309 ERROR(X509_V_ERR_CRL_PATH_VALIDATION_ERROR);
310#endif
311
312 /* The application is not happy */
313#ifdef X509_V_ERR_APPLICATION_VERIFICATION
314 ERROR(X509_V_ERR_APPLICATION_VERIFICATION);
315#endif
316 }
317#undef ERROR
318}
319
320static void
321_openssl_print_errors(void *conn, int type)
322{
323 char buf[1024];
324 do
325 {
326 unsigned long err;
327
328 err = ERR_get_error();
329 if (!err) break;
330 snprintf(buf, sizeof(buf), "OpenSSL error: %s", ERR_reason_error_string(err));
331 if (type == ECORE_CON_EVENT_CLIENT_ERROR)
332 ecore_con_event_client_error(conn, buf);
333 else
334 ecore_con_event_server_error(conn, buf);
335
336 } while (1);
337}
338
339static Eina_Bool
340_openssl_name_verify(const char *name, const char *svrname)
341{
342 if (name[0] == '*')
343 {
344 /* we allow *.domain.TLD with a wildcard, but nothing else */
345 const char *p, *s;
346
347 EINA_SAFETY_ON_TRUE_RETURN_VAL((name[1] != '.') || (!name[2]), EINA_FALSE);
348 p = strchr(name + 1, '*');
349 EINA_SAFETY_ON_TRUE_RETURN_VAL(!!p, EINA_FALSE);
350 /* verify that we have a domain of at least *.X.TLD and not *.TLD */
351 p = strchr(name + 2, '.');
352 EINA_SAFETY_ON_TRUE_RETURN_VAL(!p, EINA_FALSE);
353 s = strchr(svrname, '.');
354 EINA_SAFETY_ON_TRUE_RETURN_VAL(!s, EINA_FALSE);
355 /* same as above for the stored name */
356 EINA_SAFETY_ON_TRUE_RETURN_VAL(!strchr(s + 1, '.'), EINA_FALSE);
357 if (strcasecmp(s, name + 1))
358 {
359 ERR("%s != %s", s, name + 1);
360 return EINA_FALSE;
361 }
362 }
363 else
364 if (strcasecmp(name, svrname))
365 {
366 ERR("%s != %s", name, svrname);
367 return EINA_FALSE;
368 }
369 return EINA_TRUE;
370}
371
372static void
373_openssl_print_session(SSL *ssl)
374{
375 /* print session info into DBG */
376 SSL_SESSION *s;
377 STACK_OF(X509) *sk;
378 BIO *b;
379 char log[4096], *p;
380 int x;
381
382 if (!eina_log_domain_level_check(_ecore_con_log_dom, EINA_LOG_LEVEL_DBG)) return;
383
384 memset(log, 0, sizeof(log));
385 b = BIO_new(BIO_s_mem());
386 sk = SSL_get_peer_cert_chain(ssl);
387 if (sk)
388 {
389 DBG("CERTIFICATES:");
390 for (x = 0; x < sk_X509_num(sk); x++)
391 {
392 p = X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk, x)), log, sizeof(log));
393 DBG("%2d s:%s", x, p);
394 p = X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk, x)), log, sizeof(log));
395 DBG(" i:%s", p);
396 PEM_write_X509(stderr, sk_X509_value(sk, x));
397 }
398 }
399 s = SSL_get_session(ssl);
400 SSL_SESSION_print(b, s);
401 fprintf(stderr, "\n");
402 while (BIO_read(b, log, sizeof(log)) > 0)
403 fprintf(stderr, "%s", log);
404
405 BIO_free(b);
406}
407
408#endif
409
410#define SSL_ERROR_CHECK_GOTO_ERROR(X) \
411 do \
412 { \
413 if ((X)) \
414 { \
415 ERR("Error at %s:%s:%d!", __FILE__, __PRETTY_FUNCTION__, __LINE__); \
416 goto error; \
417 } \
418 } \
419 while (0)
420
421static Ecore_Con_Ssl_Error
422 SSL_SUFFIX(_ecore_con_ssl_init) (void);
423static Ecore_Con_Ssl_Error
424 SSL_SUFFIX(_ecore_con_ssl_shutdown) (void);
425
426static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_cafile_add) (Ecore_Con_Server * svr, const char *ca_file);
427static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_crl_add) (Ecore_Con_Server * svr, const char *crl_file);
428static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (Ecore_Con_Server * svr, const char *cert);
429static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_privkey_add) (Ecore_Con_Server * svr, const char *key_file);
430
431static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_server_prepare) (Ecore_Con_Server * svr, int ssl_type);
432static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_server_init) (Ecore_Con_Server * svr);
433static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_server_shutdown) (Ecore_Con_Server *svr);
434static int SSL_SUFFIX(_ecore_con_ssl_server_read) (Ecore_Con_Server *svr, unsigned char *buf, int size);
435static int SSL_SUFFIX(_ecore_con_ssl_server_write) (Ecore_Con_Server *svr, const unsigned char *buf, int size);
436
437static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_client_init) (Ecore_Con_Client * cl);
438static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_client_shutdown) (Ecore_Con_Client *cl);
439static int SSL_SUFFIX(_ecore_con_ssl_client_read) (Ecore_Con_Client * cl,
440 unsigned char *buf, int size);
441static int SSL_SUFFIX(_ecore_con_ssl_client_write) (Ecore_Con_Client * cl,
442 const unsigned char *buf, int size);
443
444/*
445 * General SSL API
446 */
447
448Ecore_Con_Ssl_Error
449ecore_con_ssl_init(void)
450{
451 if (!_init_con_ssl_init_count++)
452 {
453 SSL_SUFFIX(_ecore_con_ssl_init) ();
454#if _ECORE_CON_SSL_AVAILABLE != 0
455 ECORE_CON_EVENT_CLIENT_UPGRADE = ecore_event_type_new();
456 ECORE_CON_EVENT_SERVER_UPGRADE = ecore_event_type_new();
457#endif
458 }
459
460 return _init_con_ssl_init_count;
461}
462
463Ecore_Con_Ssl_Error
464ecore_con_ssl_shutdown(void)
465{
466 if (!--_init_con_ssl_init_count)
467 SSL_SUFFIX(_ecore_con_ssl_shutdown) ();
468
469 return _init_con_ssl_init_count;
470}
471
472Ecore_Con_Ssl_Error
473ecore_con_ssl_server_prepare(Ecore_Con_Server *svr,
474 int ssl_type)
475{
476 if (!ssl_type)
477 return ECORE_CON_SSL_ERROR_NONE;
478 return SSL_SUFFIX(_ecore_con_ssl_server_prepare) (svr, ssl_type);
479}
480
481Ecore_Con_Ssl_Error
482ecore_con_ssl_server_init(Ecore_Con_Server *svr)
483{
484 if (!(svr->type & ECORE_CON_SSL))
485 return ECORE_CON_SSL_ERROR_NONE;
486 return SSL_SUFFIX(_ecore_con_ssl_server_init) (svr);
487}
488
489Ecore_Con_Ssl_Error
490ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr)
491{
492 if (!(svr->type & ECORE_CON_SSL))
493 return ECORE_CON_SSL_ERROR_NONE;
494 return SSL_SUFFIX(_ecore_con_ssl_server_shutdown) (svr);
495}
496
497int
498ecore_con_ssl_server_read(Ecore_Con_Server *svr,
499 unsigned char *buf,
500 int size)
501{
502 return SSL_SUFFIX(_ecore_con_ssl_server_read) (svr, buf, size);
503}
504
505int
506ecore_con_ssl_server_write(Ecore_Con_Server *svr,
507 const unsigned char *buf,
508 int size)
509{
510 return SSL_SUFFIX(_ecore_con_ssl_server_write) (svr, buf, size);
511}
512
513Ecore_Con_Ssl_Error
514ecore_con_ssl_client_init(Ecore_Con_Client *cl)
515{
516 if (!(cl->host_server->type & ECORE_CON_SSL))
517 return ECORE_CON_SSL_ERROR_NONE;
518 return SSL_SUFFIX(_ecore_con_ssl_client_init) (cl);
519}
520
521Ecore_Con_Ssl_Error
522ecore_con_ssl_client_shutdown(Ecore_Con_Client *cl)
523{
524 if (!(cl->host_server->type & ECORE_CON_SSL))
525 return ECORE_CON_SSL_ERROR_NONE;
526 return SSL_SUFFIX(_ecore_con_ssl_client_shutdown) (cl);
527}
528
529int
530ecore_con_ssl_client_read(Ecore_Con_Client *cl,
531 unsigned char *buf,
532 int size)
533{
534 return SSL_SUFFIX(_ecore_con_ssl_client_read) (cl, buf, size);
535}
536
537int
538ecore_con_ssl_client_write(Ecore_Con_Client *cl,
539 const unsigned char *buf,
540 int size)
541{
542 return SSL_SUFFIX(_ecore_con_ssl_client_write) (cl, buf, size);
543}
544
545/**
546 * Returns if SSL support is available
547 * @return 1 if SSL is available and provided by gnutls, 2 if provided by openssl,
548 * 0 if it is not available.
549 * @ingroup Ecore_Con_Client_Group
550 */
551EAPI int
552ecore_con_ssl_available_get(void)
553{
554 return _ECORE_CON_SSL_AVAILABLE;
555}
556
557/**
558 * @addtogroup Ecore_Con_SSL_Group Ecore Connection SSL Functions
559 *
560 * Functions that operate on Ecore connection objects pertaining to SSL.
561 *
562 * @{
563 */
564
565/**
566 * @brief Enable certificate verification on a server object
567 *
568 * Call this function on a server object before main loop has started
569 * to enable verification of certificates against loaded certificates.
570 * @param svr The server object
571 */
572EAPI void
573ecore_con_ssl_server_verify(Ecore_Con_Server *svr)
574{
575 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
576 {
577 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_verify");
578 return;
579 }
580 svr->verify = EINA_TRUE;
581}
582
583/**
584 * @brief Enable hostname-based certificate verification on a server object
585 *
586 * Call this function on a server object before main loop has started
587 * to enable verification of certificates using ONLY their hostnames.
588 * @param svr The server object
589 * @note This function has no effect when used on a listening server created by
590 * ecore_con_server_add
591 * @since 1.1
592 */
593EAPI void
594ecore_con_ssl_server_verify_basic(Ecore_Con_Server *svr)
595{
596 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
597 {
598 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
599 return;
600 }
601 svr->verify_basic = EINA_TRUE;
602}
603
604/**
605 * @brief Set the hostname to verify against in certificate verification
606 *
607 * Sometimes the certificate hostname will not match the hostname that you are
608 * connecting to, and will instead match a different name. An example of this is
609 * that if you connect to talk.google.com to use Google Talk, you receive Google's
610 * certificate for gmail.com. This certificate should be trusted, and so you must call
611 * this function with "gmail.com" as @p name.
612 * See RFC2818 for more details.
613 * @param svr The server object
614 * @param name The hostname to verify against
615 * @since 1.2
616 */
617EAPI void
618ecore_con_ssl_server_verify_name_set(Ecore_Con_Server *svr, const char *name)
619{
620 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
621 {
622 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
623 return;
624 }
625 eina_stringshare_replace(&svr->verify_name, name);
626}
627
628/**
629 * @brief Get the hostname to verify against in certificate verification
630 *
631 * This function returns the name which will be used to validate the SSL certificate
632 * common name (CN) or alt name (subjectAltName). It will default to the @p name
633 * param in ecore_con_server_connect(), but can be changed with ecore_con_ssl_server_verify_name_set().
634 * @param svr The server object
635 * @return The hostname which will be used
636 * @since 1.2
637 */
638EAPI const char *
639ecore_con_ssl_server_verify_name_get(Ecore_Con_Server *svr)
640{
641 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
642 {
643 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
644 return NULL;
645 }
646 return svr->verify_name ?: svr->name;
647}
648
649/**
650 * @brief Add an ssl certificate for use in ecore_con functions.
651 *
652 * Use this function to add a SSL PEM certificate.
653 * Simply specify the cert here to use it in the server object for connecting or listening.
654 * If there is an error loading the certificate, an error will automatically be logged.
655 * @param svr The server object
656 * @param cert The path to the certificate.
657 * @return EINA_FALSE if the file cannot be loaded, otherwise EINA_TRUE.
658 */
659
660EAPI Eina_Bool
661ecore_con_ssl_server_cert_add(Ecore_Con_Server *svr,
662 const char *cert)
663{
664 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
665 {
666 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_cert_add");
667 return EINA_FALSE;
668 }
669
670 if (!svr->ssl_prepared)
671 {
672 svr->use_cert = EINA_TRUE;
673 svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
674 if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
675 return EINA_FALSE;
676 }
677
678 return SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (svr, cert);
679}
680
681/**
682 * @brief Add an ssl CA file for use in ecore_con functions.
683 *
684 * Use this function to add a SSL PEM CA file.
685 * Simply specify the file here to use it in the server object for connecting or listening.
686 * If there is an error loading the CAs, an error will automatically be logged.
687 * @param svr The server object
688 * @param ca_file The path to the CA file.
689 * @return EINA_FALSE if the file cannot be loaded, otherwise EINA_TRUE.
690 * @note since 1.2, this function can load directores
691 */
692
693EAPI Eina_Bool
694ecore_con_ssl_server_cafile_add(Ecore_Con_Server *svr,
695 const char *ca_file)
696{
697 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
698 {
699 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_cafile_add");
700 return EINA_FALSE;
701 }
702
703 if (!svr->ssl_prepared)
704 {
705 svr->use_cert = EINA_TRUE;
706 svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
707 if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
708 return EINA_FALSE;
709 }
710
711 return SSL_SUFFIX(_ecore_con_ssl_server_cafile_add) (svr, ca_file);
712}
713
714/**
715 * @brief Add an ssl private key for use in ecore_con functions.
716 *
717 * Use this function to add a SSL PEM private key
718 * Simply specify the key file here to use it in the server object for connecting or listening.
719 * If there is an error loading the key, an error will automatically be logged.
720 * @param key_file The path to the key file.
721 * @return EINA_FALSE if the file cannot be loaded,
722 * otherwise EINA_TRUE.
723 */
724
725EAPI Eina_Bool
726ecore_con_ssl_server_privkey_add(Ecore_Con_Server *svr,
727 const char *key_file)
728{
729 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
730 {
731 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_privkey_add");
732 return EINA_FALSE;
733 }
734
735 if (!svr->ssl_prepared)
736 {
737 svr->use_cert = EINA_TRUE;
738 svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
739 if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
740 return EINA_FALSE;
741 }
742
743 return SSL_SUFFIX(_ecore_con_ssl_server_privkey_add) (svr, key_file);
744}
745
746/**
747 * @brief Add an ssl CRL for use in ecore_con functions.
748 *
749 * Use this function to add a SSL PEM CRL file
750 * Simply specify the CRL file here to use it in the server object for connecting or listening.
751 * If there is an error loading the CRL, an error will automatically be logged.
752 * @param svr The server object
753 * @param crl_file The path to the CRL file.
754 * @return EINA_FALSE if the file cannot be loaded,
755 * otherwise EINA_TRUE.
756 */
757
758EAPI Eina_Bool
759ecore_con_ssl_server_crl_add(Ecore_Con_Server *svr,
760 const char *crl_file)
761{
762 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
763 {
764 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_crl_add");
765 return EINA_FALSE;
766 }
767
768 if (!svr->ssl_prepared)
769 {
770 svr->use_cert = EINA_TRUE;
771 svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
772 if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
773 return EINA_FALSE;
774 }
775
776 return SSL_SUFFIX(_ecore_con_ssl_server_crl_add) (svr, crl_file);
777}
778
779/**
780 * @brief Upgrade a connection to a specified level of encryption
781 *
782 * Use this function to begin an SSL handshake on a connection (STARTTLS or similar).
783 * Once the upgrade has been completed, an ECORE_CON_EVENT_SERVER_UPGRADE event will be emitted.
784 * The connection should be treated as disconnected until the next event.
785 * @param svr The server object
786 * @param ssl_type The SSL connection type (ONLY).
787 * @return EINA_FALSE if the connection cannot be upgraded, otherwise EINA_TRUE.
788 * @note This function is NEVER to be used on a server object created with ecore_con_server_add
789 * @warning Setting a wrong value for @p compl_type WILL mess up your program.
790 * @since 1.1
791 */
792
793EAPI Eina_Bool
794ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type ssl_type)
795{
796 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
797 {
798 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
799 return EINA_FALSE;
800 }
801#if _ECORE_CON_SSL_AVAILABLE == 0
802 return EINA_FALSE;
803#endif
804
805 if (!svr->ssl_prepared)
806 {
807 if (ecore_con_ssl_server_prepare(svr, ssl_type))
808 return EINA_FALSE;
809 }
810 if (!svr->use_cert)
811 svr->type |= ssl_type;
812 svr->upgrade = EINA_TRUE;
813 svr->handshaking = EINA_TRUE;
814 svr->ssl_state = ECORE_CON_SSL_STATE_INIT;
815 return !SSL_SUFFIX(_ecore_con_ssl_server_init) (svr);
816}
817
818/**
819 * @brief Upgrade a connection to a specified level of encryption
820 *
821 * Use this function to begin an SSL handshake on a connection (STARTTLS or similar).
822 * Once the upgrade has been completed, an ECORE_CON_EVENT_CLIENT_UPGRADE event will be emitted.
823 * The connection should be treated as disconnected until the next event.
824 * @param cl The client object
825 * @param ssl_type The SSL connection type (ONLY).
826 * @return EINA_FALSE if the connection cannot be upgraded, otherwise EINA_TRUE.
827 * @warning Setting a wrong value for @p compl_type WILL mess up your program.
828 * @since 1.1
829 */
830
831EAPI Eina_Bool
832ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type ssl_type)
833{
834 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
835 {
836 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, __func__);
837 return EINA_FALSE;
838 }
839#if _ECORE_CON_SSL_AVAILABLE == 0
840 return EINA_FALSE;
841#endif
842
843 if (!cl->host_server->ssl_prepared)
844 {
845 if (ecore_con_ssl_server_prepare(cl->host_server, ssl_type))
846 return EINA_FALSE;
847 }
848 if (!cl->host_server->use_cert)
849 cl->host_server->type |= ssl_type;
850 cl->upgrade = EINA_TRUE;
851 cl->host_server->upgrade = EINA_TRUE;
852 cl->handshaking = EINA_TRUE;
853 cl->ssl_state = ECORE_CON_SSL_STATE_INIT;
854 return SSL_SUFFIX(_ecore_con_ssl_client_init) (cl);
855}
856
857/**
858 * @}
859 */
860
861#if USE_GNUTLS
862
863/*
864 * GnuTLS
865 */
866
867static Ecore_Con_Ssl_Error
868_ecore_con_ssl_init_gnutls(void)
869{
870#ifdef EINA_HAVE_THREADS
871 if (gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread))
872 WRN("YOU ARE USING PTHREADS, BUT I CANNOT INITIALIZE THREADSAFE GCRYPT OPERATIONS!");
873#endif
874 if (gnutls_global_init())
875 return ECORE_CON_SSL_ERROR_INIT_FAILED;
876
877#ifdef ISCOMFITOR
878 if (eina_log_domain_level_check(_ecore_con_log_dom, EINA_LOG_LEVEL_DBG))
879 {
880 gnutls_global_set_log_level(9);
881 gnutls_global_set_log_function(_gnutls_log_func);
882 }
883#endif
884 return ECORE_CON_SSL_ERROR_NONE;
885}
886
887static Ecore_Con_Ssl_Error
888_ecore_con_ssl_shutdown_gnutls(void)
889{
890 gnutls_global_deinit();
891
892 return ECORE_CON_SSL_ERROR_NONE;
893}
894
895static Ecore_Con_Ssl_Error
896_ecore_con_ssl_server_prepare_gnutls(Ecore_Con_Server *svr,
897 int ssl_type)
898{
899 int ret;
900
901 if (ssl_type & ECORE_CON_USE_SSL2)
902 return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
903
904 switch (ssl_type)
905 {
906 case ECORE_CON_USE_SSL3:
907 case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
908 case ECORE_CON_USE_TLS:
909 case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
910 case ECORE_CON_USE_MIXED:
911 case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
912 break;
913
914 default:
915 return ECORE_CON_SSL_ERROR_NONE;
916 }
917
918 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_allocate_credentials(&svr->cert));
919
920 if (svr->use_cert)
921 {
922 if (svr->created)
923 {
924 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_dh_params_init(&svr->dh_params));
925 INF("Generating DH params");
926 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_dh_params_generate2(svr->dh_params, 1024));
927
928 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_anon_allocate_server_credentials(&svr->anoncred_s));
929 /* TODO: implement PSK */
930 // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_psk_allocate_server_credentials(&svr->pskcred_s));
931
932 gnutls_anon_set_server_dh_params(svr->anoncred_s, svr->dh_params);
933 gnutls_certificate_set_dh_params(svr->cert, svr->dh_params);
934 //gnutls_psk_set_server_dh_params(svr->pskcred_s, svr->dh_params);
935 INF("DH params successfully generated and applied!");
936 }
937 else
938 {
939 //SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_psk_allocate_client_credentials(&svr->pskcred_c));
940 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_anon_allocate_client_credentials(&svr->anoncred_c));
941 }
942 }
943
944 svr->ssl_prepared = EINA_TRUE;
945 return ECORE_CON_SSL_ERROR_NONE;
946
947error:
948 _gnutls_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR, ret);
949 _ecore_con_ssl_server_shutdown_gnutls(svr);
950 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
951}
952
953
954static Ecore_Con_Ssl_Error
955_ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr)
956{
957 const gnutls_datum_t *cert_list;
958 unsigned int iter, cert_list_size;
959 gnutls_x509_crt_t cert = NULL;
960 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";
961 int ret = 0;
962
963 switch (svr->ssl_state)
964 {
965 case ECORE_CON_SSL_STATE_DONE:
966 return ECORE_CON_SSL_ERROR_NONE;
967
968 case ECORE_CON_SSL_STATE_INIT:
969 if (svr->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */
970 return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
971
972 switch (svr->type & ECORE_CON_SSL)
973 {
974 case ECORE_CON_USE_SSL3:
975 case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
976 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";
977 break;
978
979 case ECORE_CON_USE_TLS:
980 case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
981 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";
982 break;
983
984 case ECORE_CON_USE_MIXED:
985 case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
986 break;
987
988 default:
989 return ECORE_CON_SSL_ERROR_NONE;
990 }
991
992 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&svr->session, GNUTLS_CLIENT));
993 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_enable_client(svr->session));
994 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_server_name_set(svr->session, GNUTLS_NAME_DNS, svr->name, strlen(svr->name)));
995 INF("Applying priority string: %s", priority);
996 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_priority_set_direct(svr->session, priority, NULL));
997 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_CERTIFICATE, svr->cert));
998 // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_PSK, svr->pskcred_c));
999 if (!svr->use_cert)
1000 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_ANON, svr->anoncred_c));
1001
1002 gnutls_dh_set_prime_bits(svr->session, 512);
1003 gnutls_transport_set_ptr(svr->session, (gnutls_transport_ptr_t)((intptr_t)svr->fd));
1004 svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1005
1006 case ECORE_CON_SSL_STATE_HANDSHAKING:
1007 if (!svr->session)
1008 {
1009 DBG("Server was previously lost, going to error condition");
1010 goto error;
1011 }
1012 ret = gnutls_handshake(svr->session);
1013 DBG("calling gnutls_handshake(): returned with '%s'", gnutls_strerror_name(ret));
1014 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret));
1015 if (!ret)
1016 {
1017 svr->handshaking = EINA_FALSE;
1018 svr->ssl_state = ECORE_CON_SSL_STATE_DONE;
1019 }
1020 else
1021 {
1022 if (gnutls_record_get_direction(svr->session))
1023 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
1024 else
1025 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1026 return ECORE_CON_SSL_ERROR_NONE;
1027 }
1028
1029 default:
1030 break;
1031 }
1032
1033 if ((!svr->verify) && (!svr->verify_basic))
1034 /* not verifying certificates, so we're done! */
1035 return ECORE_CON_SSL_ERROR_NONE;
1036 if (svr->verify)
1037 {
1038 /* use CRL/CA lists to verify */
1039 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_verify_peers2(svr->session, &iter));
1040 if (iter & GNUTLS_CERT_INVALID)
1041 ERR("The certificate is not trusted.");
1042 else if (iter & GNUTLS_CERT_SIGNER_NOT_FOUND)
1043 ERR("The certificate hasn't got a known issuer.");
1044 else if (iter & GNUTLS_CERT_REVOKED)
1045 ERR("The certificate has been revoked.");
1046 else if (iter & GNUTLS_CERT_EXPIRED)
1047 ERR("The certificate has expired");
1048 else if (iter & GNUTLS_CERT_NOT_ACTIVATED)
1049 ERR("The certificate is not yet activated");
1050
1051 if (iter)
1052 goto error;
1053 }
1054 if (gnutls_certificate_type_get(svr->session) != GNUTLS_CRT_X509)
1055 {
1056 ERR("Warning: PGP certificates are not yet supported!");
1057 goto error;
1058 }
1059
1060 SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(svr->session, &cert_list_size)));
1061 SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size);
1062
1063 _gnutls_print_session(cert_list, cert_list_size);
1064
1065 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert));
1066 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER));
1067
1068 SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, svr->verify_name ?: svr->name));
1069 gnutls_x509_crt_deinit(cert);
1070 DBG("SSL certificate verification succeeded!");
1071 return ECORE_CON_SSL_ERROR_NONE;
1072
1073error:
1074 _gnutls_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR, ret);
1075 if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED))
1076 ERR("Also received alert: %s", gnutls_alert_get_name(gnutls_alert_get(svr->session)));
1077 if (svr->session && (svr->ssl_state != ECORE_CON_SSL_STATE_DONE))
1078 {
1079 ERR("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_out(svr->session)));
1080 ERR("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_in(svr->session)));
1081 }
1082 if (cert)
1083 gnutls_x509_crt_deinit(cert);
1084 _ecore_con_ssl_server_shutdown_gnutls(svr);
1085 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
1086}
1087
1088static Eina_Bool
1089_ecore_con_ssl_server_cafile_add_gnutls(Ecore_Con_Server *svr,
1090 const char *ca_file)
1091{
1092 struct stat st;
1093 Eina_Iterator *it;
1094 const char *file;
1095 Eina_Bool error = EINA_FALSE;
1096
1097 if (stat(ca_file, &st)) return EINA_FALSE;
1098 if (S_ISDIR(st.st_mode))
1099 {
1100 it = eina_file_ls(ca_file);
1101 SSL_ERROR_CHECK_GOTO_ERROR(!it);
1102 EINA_ITERATOR_FOREACH(it, file)
1103 {
1104 if (!error)
1105 {
1106 if (gnutls_certificate_set_x509_trust_file(svr->cert, file, GNUTLS_X509_FMT_PEM) < 1)
1107 error++;
1108 }
1109 eina_stringshare_del(file);
1110 }
1111 eina_iterator_free(it);
1112 }
1113 else
1114 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_trust_file(svr->cert, ca_file,
1115 GNUTLS_X509_FMT_PEM) < 1);
1116
1117 return !error;
1118error:
1119 ERR("Could not load CA file!");
1120 return EINA_FALSE;
1121}
1122
1123static Eina_Bool
1124_ecore_con_ssl_server_crl_add_gnutls(Ecore_Con_Server *svr,
1125 const char *crl_file)
1126{
1127 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_crl_file(svr->cert, crl_file,
1128 GNUTLS_X509_FMT_PEM) < 1);
1129
1130 return EINA_TRUE;
1131error:
1132 ERR("Could not load CRL file!");
1133 return EINA_FALSE;
1134}
1135
1136static Eina_Bool
1137_ecore_con_ssl_server_privkey_add_gnutls(Ecore_Con_Server *svr,
1138 const char *key_file)
1139{
1140 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_key_file(svr->cert, svr->cert_file, key_file,
1141 GNUTLS_X509_FMT_PEM));
1142
1143 return EINA_TRUE;
1144error:
1145 ERR("Could not load certificate/key file!");
1146 return EINA_FALSE;
1147}
1148
1149static Eina_Bool
1150_ecore_con_ssl_server_cert_add_gnutls(Ecore_Con_Server *svr,
1151 const char *cert_file)
1152{
1153 if (!(svr->cert_file = strdup(cert_file)))
1154 return EINA_FALSE;
1155
1156 return EINA_TRUE;
1157}
1158
1159static Ecore_Con_Ssl_Error
1160_ecore_con_ssl_server_shutdown_gnutls(Ecore_Con_Server *svr)
1161{
1162 if (svr->session)
1163 {
1164 gnutls_bye(svr->session, GNUTLS_SHUT_RDWR);
1165 gnutls_deinit(svr->session);
1166 }
1167
1168 free(svr->cert_file);
1169 svr->cert_file = NULL;
1170 if (svr->cert)
1171 gnutls_certificate_free_credentials(svr->cert);
1172 svr->cert = NULL;
1173
1174 if ((svr->type & ECORE_CON_SSL) && svr->created)
1175 {
1176 if (svr->dh_params)
1177 {
1178 gnutls_dh_params_deinit(svr->dh_params);
1179 svr->dh_params = NULL;
1180 }
1181 if (svr->anoncred_s)
1182 gnutls_anon_free_server_credentials(svr->anoncred_s);
1183 // if (svr->pskcred_s)
1184 // gnutls_psk_free_server_credentials(svr->pskcred_s);
1185
1186 svr->anoncred_s = NULL;
1187 svr->pskcred_s = NULL;
1188 }
1189 else if (svr->type & ECORE_CON_SSL)
1190 {
1191 if (svr->anoncred_c)
1192 gnutls_anon_free_client_credentials(svr->anoncred_c);
1193 // if (svr->pskcred_c)
1194 // gnutls_psk_free_client_credentials(svr->pskcred_c);
1195
1196 svr->anoncred_c = NULL;
1197 svr->pskcred_c = NULL;
1198 }
1199
1200 svr->session = NULL;
1201
1202 return ECORE_CON_SSL_ERROR_NONE;
1203}
1204
1205static int
1206_ecore_con_ssl_server_read_gnutls(Ecore_Con_Server *svr,
1207 unsigned char *buf,
1208 int size)
1209{
1210 int num;
1211
1212 if (svr->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING)
1213 {
1214 DBG("Continuing gnutls handshake");
1215 if (!_ecore_con_ssl_server_init_gnutls(svr))
1216 return 0;
1217 return -1;
1218 }
1219
1220 num = gnutls_record_recv(svr->session, buf, size);
1221 if (num > 0)
1222 return num;
1223
1224 if (num == GNUTLS_E_REHANDSHAKE)
1225 {
1226 WRN("Rehandshake request ignored");
1227 return 0;
1228
1229 svr->handshaking = EINA_TRUE;
1230 svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1231 if (!_ecore_con_ssl_server_init_gnutls(svr))
1232 return 0;
1233 }
1234 else if ((!gnutls_error_is_fatal(num)) && (num != GNUTLS_E_SUCCESS))
1235 return 0;
1236
1237 return -1;
1238}
1239
1240static int
1241_ecore_con_ssl_server_write_gnutls(Ecore_Con_Server *svr,
1242 const unsigned char *buf,
1243 int size)
1244{
1245 int num;
1246
1247 if (svr->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING)
1248 {
1249 DBG("Continuing gnutls handshake");
1250 if (!_ecore_con_ssl_server_init_gnutls(svr))
1251 return 0;
1252 return -1;
1253 }
1254
1255 num = gnutls_record_send(svr->session, buf, size);
1256 if (num > 0)
1257 return num;
1258
1259 if (num == GNUTLS_E_REHANDSHAKE)
1260 {
1261 WRN("Rehandshake request ignored");
1262 return 0;
1263/* this is only partly functional I think? */
1264 svr->handshaking = EINA_TRUE;
1265 svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1266 if (!_ecore_con_ssl_server_init_gnutls(svr))
1267 return 0;
1268 }
1269 else if (!gnutls_error_is_fatal(num))
1270 return 0;
1271
1272 return -1;
1273}
1274
1275static Ecore_Con_Ssl_Error
1276_ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
1277{
1278 const gnutls_datum_t *cert_list;
1279 unsigned int iter, cert_list_size;
1280 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";
1281 int ret = 0;
1282
1283 switch (cl->ssl_state)
1284 {
1285 case ECORE_CON_SSL_STATE_DONE:
1286 return ECORE_CON_SSL_ERROR_NONE;
1287
1288 case ECORE_CON_SSL_STATE_INIT:
1289 if (cl->host_server->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */
1290 return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
1291
1292 switch (cl->host_server->type & ECORE_CON_SSL)
1293 {
1294 case ECORE_CON_USE_SSL3:
1295 case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
1296 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";
1297 break;
1298
1299 case ECORE_CON_USE_TLS:
1300 case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
1301 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";
1302 break;
1303
1304 case ECORE_CON_USE_MIXED:
1305 case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
1306 break;
1307
1308 default:
1309 return ECORE_CON_SSL_ERROR_NONE;
1310 }
1311
1312 _client_connected++;
1313
1314 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&cl->session, GNUTLS_SERVER));
1315 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_key_generate(&cl->session_ticket));
1316 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_enable_server(cl->session, &cl->session_ticket));
1317 INF("Applying priority string: %s", priority);
1318 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_priority_set_direct(cl->session, priority, NULL));
1319 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_CERTIFICATE, cl->host_server->cert));
1320 // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_PSK, cl->host_server->pskcred_s));
1321 if (!cl->host_server->use_cert)
1322 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_ANON, cl->host_server->anoncred_s));
1323
1324 gnutls_certificate_server_set_request(cl->session, GNUTLS_CERT_REQUEST);
1325
1326 gnutls_dh_set_prime_bits(cl->session, 2048);
1327 gnutls_transport_set_ptr(cl->session, (gnutls_transport_ptr_t)((intptr_t)cl->fd));
1328 cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1329
1330 case ECORE_CON_SSL_STATE_HANDSHAKING:
1331 if (!cl->session)
1332 {
1333 DBG("Client was previously lost, going to error condition");
1334 goto error;
1335 }
1336 DBG("calling gnutls_handshake()");
1337 ret = gnutls_handshake(cl->session);
1338 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret));
1339
1340 if (!ret)
1341 {
1342 cl->handshaking = EINA_FALSE;
1343 cl->ssl_state = ECORE_CON_SSL_STATE_DONE;
1344 }
1345 else
1346 {
1347 if (gnutls_record_get_direction(cl->session))
1348 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
1349 else
1350 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
1351 return ECORE_CON_SSL_ERROR_NONE;
1352 }
1353
1354 default:
1355 break;
1356 }
1357
1358 if (!cl->host_server->verify)
1359 /* not verifying certificates, so we're done! */
1360 return ECORE_CON_SSL_ERROR_NONE;
1361 /* use CRL/CA lists to verify */
1362 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_verify_peers2(cl->session, &iter));
1363 if (iter & GNUTLS_CERT_INVALID)
1364 ERR("The certificate is not trusted.");
1365 else if (iter & GNUTLS_CERT_SIGNER_NOT_FOUND)
1366 ERR("The certificate hasn't got a known issuer.");
1367 else if (iter & GNUTLS_CERT_REVOKED)
1368 ERR("The certificate has been revoked.");
1369 else if (iter & GNUTLS_CERT_EXPIRED)
1370 ERR("The certificate has expired");
1371 else if (iter & GNUTLS_CERT_NOT_ACTIVATED)
1372 ERR("The certificate is not yet activated");
1373
1374 if (iter)
1375 goto error;
1376 if (gnutls_certificate_type_get(cl->session) != GNUTLS_CRT_X509)
1377 {
1378 ERR("Warning: PGP certificates are not yet supported!");
1379 goto error;
1380 }
1381
1382 SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(cl->session, &cert_list_size)));
1383 SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size);
1384
1385 _gnutls_print_session(cert_list, cert_list_size);
1386/*
1387 gnutls_x509_crt_t cert = NULL;
1388 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert));
1389 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER));
1390
1391 SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, cl->host_server->name));
1392 gnutls_x509_crt_deinit(cert);
1393*/
1394 DBG("SSL certificate verification succeeded!");
1395 return ECORE_CON_SSL_ERROR_NONE;
1396
1397error:
1398 _gnutls_print_errors(cl, ECORE_CON_EVENT_CLIENT_ERROR, ret);
1399 if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED))
1400 ERR("Also received alert: %s", gnutls_alert_get_name(gnutls_alert_get(cl->session)));
1401 if (cl->session && (cl->ssl_state != ECORE_CON_SSL_STATE_DONE))
1402 {
1403 ERR("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_out(cl->session)));
1404 ERR("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_in(cl->session)));
1405 }
1406/*
1407 if (cert)
1408 gnutls_x509_crt_deinit(cert);
1409*/
1410 _ecore_con_ssl_client_shutdown_gnutls(cl);
1411 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
1412}
1413
1414static Ecore_Con_Ssl_Error
1415_ecore_con_ssl_client_shutdown_gnutls(Ecore_Con_Client *cl)
1416{
1417 if (cl->session)
1418 {
1419 gnutls_bye(cl->session, GNUTLS_SHUT_RDWR);
1420 gnutls_deinit(cl->session);
1421 gnutls_free(cl->session_ticket.data);
1422 cl->session_ticket.data = NULL;
1423 }
1424
1425 cl->session = NULL;
1426
1427 return ECORE_CON_SSL_ERROR_NONE;
1428}
1429
1430static int
1431_ecore_con_ssl_client_read_gnutls(Ecore_Con_Client *cl,
1432 unsigned char *buf,
1433 int size)
1434{
1435 int num;
1436
1437 if (cl->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING)
1438 {
1439 if (!_ecore_con_ssl_client_init_gnutls(cl))
1440 return 0;
1441 return -1;
1442 }
1443
1444 num = gnutls_record_recv(cl->session, buf, size);
1445 if (num > 0)
1446 return num;
1447
1448 if (num == GNUTLS_E_REHANDSHAKE)
1449 {
1450 WRN("Rehandshake request ignored");
1451 return 0;
1452 cl->handshaking = EINA_TRUE;
1453 cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1454 if (!_ecore_con_ssl_client_init_gnutls(cl))
1455 return 0;
1456 WRN("Rehandshake request ignored");
1457 return 0;
1458 }
1459 else if ((!gnutls_error_is_fatal(num)) && (num != GNUTLS_E_SUCCESS))
1460 return 0;
1461
1462 return -1;
1463}
1464
1465static int
1466_ecore_con_ssl_client_write_gnutls(Ecore_Con_Client *cl,
1467 const unsigned char *buf,
1468 int size)
1469{
1470 int num;
1471
1472 if (cl->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING)
1473 {
1474 if (!_ecore_con_ssl_client_init_gnutls(cl))
1475 return 0;
1476 return -1;
1477 }
1478
1479 num = gnutls_record_send(cl->session, buf, size);
1480 if (num > 0)
1481 return num;
1482
1483 if (num == GNUTLS_E_REHANDSHAKE)
1484 {
1485 WRN("Rehandshake request ignored");
1486 return 0;
1487 cl->handshaking = EINA_TRUE;
1488 cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1489 if (!_ecore_con_ssl_client_init_gnutls(cl))
1490 return 0;
1491 }
1492 else if (!gnutls_error_is_fatal(num))
1493 return 0;
1494
1495 return -1;
1496}
1497
1498#elif USE_OPENSSL && !USE_GNUTLS
1499
1500/*
1501 * OpenSSL
1502 */
1503
1504static Ecore_Con_Ssl_Error
1505_ecore_con_ssl_init_openssl(void)
1506{
1507 SSL_library_init();
1508 SSL_load_error_strings();
1509 OpenSSL_add_all_algorithms();
1510
1511 return ECORE_CON_SSL_ERROR_NONE;
1512}
1513
1514static Ecore_Con_Ssl_Error
1515_ecore_con_ssl_shutdown_openssl(void)
1516{
1517 ERR_free_strings();
1518 EVP_cleanup();
1519 return ECORE_CON_SSL_ERROR_NONE;
1520}
1521
1522static Ecore_Con_Ssl_Error
1523_ecore_con_ssl_server_prepare_openssl(Ecore_Con_Server *svr,
1524 int ssl_type)
1525{
1526 long options;
1527 int dh = 0;
1528
1529 if (ssl_type & ECORE_CON_USE_SSL2)
1530 return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
1531
1532 switch (ssl_type)
1533 {
1534 case ECORE_CON_USE_SSL3:
1535 case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
1536 if (!svr->created)
1537 SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())));
1538 else
1539 SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_server_method())));
1540 break;
1541
1542 case ECORE_CON_USE_TLS:
1543 case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
1544 if (!svr->created)
1545 SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())));
1546 else
1547 SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_server_method())));
1548 break;
1549
1550 case ECORE_CON_USE_MIXED:
1551 case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
1552 if (!svr->created)
1553 SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_client_method())));
1554 else
1555 SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_server_method())));
1556 options = SSL_CTX_get_options(svr->ssl_ctx);
1557 SSL_CTX_set_options(svr->ssl_ctx, options | SSL_OP_NO_SSLv2 | SSL_OP_SINGLE_DH_USE);
1558 break;
1559
1560 default:
1561 return ECORE_CON_SSL_ERROR_NONE;
1562 }
1563
1564 if ((!svr->use_cert) && svr->created)
1565 {
1566 DH *dh_params;
1567 INF("Generating DH params");
1568 SSL_ERROR_CHECK_GOTO_ERROR(!(dh_params = DH_new()));
1569 SSL_ERROR_CHECK_GOTO_ERROR(!DH_generate_parameters_ex(dh_params, 1024, DH_GENERATOR_5, NULL));
1570 SSL_ERROR_CHECK_GOTO_ERROR(!DH_check(dh_params, &dh));
1571 SSL_ERROR_CHECK_GOTO_ERROR((dh & DH_CHECK_P_NOT_PRIME) || (dh & DH_CHECK_P_NOT_SAFE_PRIME));
1572 SSL_ERROR_CHECK_GOTO_ERROR(!DH_generate_key(dh_params));
1573 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_tmp_dh(svr->ssl_ctx, dh_params));
1574 DH_free(dh_params);
1575 INF("DH params successfully generated and applied!");
1576 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_cipher_list(svr->ssl_ctx, "aNULL:!eNULL:!LOW:!EXPORT:@STRENGTH"));
1577 }
1578 else if (!svr->use_cert)
1579 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_cipher_list(svr->ssl_ctx, "aNULL:!eNULL:!LOW:!EXPORT:!ECDH:RSA:AES:!PSK:@STRENGTH"));
1580
1581 return ECORE_CON_SSL_ERROR_NONE;
1582
1583error:
1584 if (dh)
1585 {
1586 if (dh & DH_CHECK_P_NOT_PRIME)
1587 ERR("openssl error: dh_params could not generate a prime!");
1588 else
1589 ERR("openssl error: dh_params could not generate a safe prime!");
1590 }
1591 else
1592 _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1593 _ecore_con_ssl_server_shutdown_openssl(svr);
1594 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
1595}
1596
1597static Ecore_Con_Ssl_Error
1598_ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr)
1599{
1600 int ret = -1;
1601
1602 switch (svr->ssl_state)
1603 {
1604 case ECORE_CON_SSL_STATE_DONE:
1605 return ECORE_CON_SSL_ERROR_NONE;
1606
1607 case ECORE_CON_SSL_STATE_INIT:
1608 SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl = SSL_new(svr->ssl_ctx)));
1609
1610 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(svr->ssl, svr->fd));
1611 SSL_set_connect_state(svr->ssl);
1612 svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1613
1614 case ECORE_CON_SSL_STATE_HANDSHAKING:
1615 if (!svr->ssl)
1616 {
1617 DBG("Server was previously lost, going to error condition");
1618 goto error;
1619 }
1620 ret = SSL_do_handshake(svr->ssl);
1621 svr->ssl_err = SSL_get_error(svr->ssl, ret);
1622 SSL_ERROR_CHECK_GOTO_ERROR((svr->ssl_err == SSL_ERROR_SYSCALL) || (svr->ssl_err == SSL_ERROR_SSL));
1623
1624 if (ret == 1)
1625 {
1626 svr->handshaking = EINA_FALSE;
1627 svr->ssl_state = ECORE_CON_SSL_STATE_DONE;
1628 }
1629 else
1630 {
1631 if (svr->ssl_err == SSL_ERROR_WANT_READ)
1632 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1633 else if (svr->ssl_err == SSL_ERROR_WANT_WRITE)
1634 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
1635 return ECORE_CON_SSL_ERROR_NONE;
1636 }
1637
1638 default:
1639 break;
1640 }
1641
1642 _openssl_print_session(svr->ssl);
1643 if ((!svr->verify) && (!svr->verify_basic))
1644 /* not verifying certificates, so we're done! */
1645 return ECORE_CON_SSL_ERROR_NONE;
1646
1647 {
1648 X509 *cert;
1649 SSL_set_verify(svr->ssl, SSL_VERIFY_PEER, NULL);
1650 /* use CRL/CA lists to verify */
1651 cert = SSL_get_peer_certificate(svr->ssl);
1652 if (cert)
1653 {
1654 char *c;
1655 int clen;
1656 int name = 0;
1657
1658 if (svr->verify)
1659 {
1660 int err;
1661
1662 err = SSL_get_verify_result(svr->ssl);
1663 _openssl_print_verify_error(err);
1664 SSL_ERROR_CHECK_GOTO_ERROR(err);
1665 }
1666 clen = X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_subject_alt_name, NULL, 0);
1667 if (clen > 0)
1668 name = NID_subject_alt_name;
1669 else
1670 clen = X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, NULL, 0);
1671 SSL_ERROR_CHECK_GOTO_ERROR(clen < 1);
1672 if (!name) name = NID_commonName;
1673 c = alloca(++clen);
1674 X509_NAME_get_text_by_NID(X509_get_subject_name(cert), name, c, clen);
1675 INF("CERT NAME: %s\n", c);
1676 SSL_ERROR_CHECK_GOTO_ERROR(!_openssl_name_verify(c, svr->verify_name ?: svr->name));
1677 }
1678 }
1679
1680 DBG("SSL certificate verification succeeded!");
1681
1682 return ECORE_CON_SSL_ERROR_NONE;
1683
1684error:
1685 _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1686 _ecore_con_ssl_server_shutdown_openssl(svr);
1687 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
1688}
1689
1690static Eina_Bool
1691_ecore_con_ssl_server_cafile_add_openssl(Ecore_Con_Server *svr,
1692 const char *ca_file)
1693{
1694 struct stat st;
1695
1696 if (stat(ca_file, &st)) return EINA_FALSE;
1697 if (S_ISDIR(st.st_mode))
1698 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_load_verify_locations(svr->ssl_ctx, NULL, ca_file));
1699 else
1700 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_load_verify_locations(svr->ssl_ctx, ca_file, NULL));
1701 return EINA_TRUE;
1702
1703error:
1704 _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1705 return EINA_FALSE;
1706}
1707
1708static Eina_Bool
1709_ecore_con_ssl_server_crl_add_openssl(Ecore_Con_Server *svr,
1710 const char *crl_file)
1711{
1712 X509_STORE *st;
1713 X509_LOOKUP *lu;
1714 static Eina_Bool flag = EINA_FALSE;
1715
1716 SSL_ERROR_CHECK_GOTO_ERROR(!(st = SSL_CTX_get_cert_store(svr->ssl_ctx)));
1717 SSL_ERROR_CHECK_GOTO_ERROR(!(lu = X509_STORE_add_lookup(st, X509_LOOKUP_file())));
1718 SSL_ERROR_CHECK_GOTO_ERROR(X509_load_crl_file(lu, crl_file, X509_FILETYPE_PEM) < 1);
1719 if (!flag)
1720 {
1721 X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
1722 flag = EINA_TRUE;
1723 }
1724
1725 return EINA_TRUE;
1726
1727error:
1728 _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1729 return EINA_FALSE;
1730}
1731
1732static Eina_Bool
1733_ecore_con_ssl_server_privkey_add_openssl(Ecore_Con_Server *svr,
1734 const char *key_file)
1735{
1736 FILE *fp = NULL;
1737 EVP_PKEY *privkey = NULL;
1738
1739 if (!(fp = fopen(key_file, "r")))
1740 goto error;
1741
1742 SSL_ERROR_CHECK_GOTO_ERROR(!(privkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL)));
1743
1744 fclose(fp);
1745 SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_PrivateKey(svr->ssl_ctx, privkey) < 1);
1746 SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_check_private_key(svr->ssl_ctx) < 1);
1747
1748 return EINA_TRUE;
1749
1750error:
1751 if (fp)
1752 fclose(fp);
1753 _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1754 return EINA_FALSE;
1755}
1756
1757static Eina_Bool
1758_ecore_con_ssl_server_cert_add_openssl(Ecore_Con_Server *svr,
1759 const char *cert_file)
1760{
1761 FILE *fp = NULL;
1762 X509 *cert = NULL;
1763
1764 if (!(fp = fopen(cert_file, "r")))
1765 goto error;
1766
1767 SSL_ERROR_CHECK_GOTO_ERROR(!(cert = PEM_read_X509(fp, NULL, NULL, NULL)));
1768
1769 fclose(fp);
1770
1771 SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_certificate(svr->ssl_ctx, cert) < 1);
1772
1773 return EINA_TRUE;
1774
1775error:
1776 if (fp)
1777 fclose(fp);
1778 _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1779 return EINA_FALSE;
1780}
1781
1782static Ecore_Con_Ssl_Error
1783_ecore_con_ssl_server_shutdown_openssl(Ecore_Con_Server *svr)
1784{
1785 if (svr->ssl)
1786 {
1787 if (!SSL_shutdown(svr->ssl))
1788 SSL_shutdown(svr->ssl);
1789
1790 SSL_free(svr->ssl);
1791 }
1792
1793 if (svr->ssl_ctx)
1794 SSL_CTX_free(svr->ssl_ctx);
1795
1796 svr->ssl = NULL;
1797 svr->ssl_ctx = NULL;
1798 svr->ssl_err = SSL_ERROR_NONE;
1799
1800 return ECORE_CON_SSL_ERROR_NONE;
1801}
1802
1803static int
1804_ecore_con_ssl_server_read_openssl(Ecore_Con_Server *svr,
1805 unsigned char *buf,
1806 int size)
1807{
1808 int num;
1809
1810 if (!svr->ssl) return -1;
1811 num = SSL_read(svr->ssl, buf, size);
1812 svr->ssl_err = SSL_get_error(svr->ssl, num);
1813
1814 if (svr->fd_handler)
1815 {
1816 if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ)
1817 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1818 else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE)
1819 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
1820 }
1821
1822 if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
1823 (svr->ssl_err == SSL_ERROR_SYSCALL) ||
1824 (svr->ssl_err == SSL_ERROR_SSL))
1825 return -1;
1826
1827 if (num < 0)
1828 return 0;
1829
1830 return num;
1831}
1832
1833static int
1834_ecore_con_ssl_server_write_openssl(Ecore_Con_Server *svr,
1835 const unsigned char *buf,
1836 int size)
1837{
1838 int num;
1839
1840 num = SSL_write(svr->ssl, buf, size);
1841 svr->ssl_err = SSL_get_error(svr->ssl, num);
1842
1843 if (svr->fd_handler)
1844 {
1845 if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ)
1846 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1847 else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE)
1848 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
1849 }
1850
1851 if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
1852 (svr->ssl_err == SSL_ERROR_SYSCALL) ||
1853 (svr->ssl_err == SSL_ERROR_SSL))
1854 return -1;
1855
1856 if (num < 0)
1857 return 0;
1858
1859 return num;
1860}
1861
1862static Ecore_Con_Ssl_Error
1863_ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl)
1864{
1865 int ret = -1;
1866 switch (cl->ssl_state)
1867 {
1868 case ECORE_CON_SSL_STATE_DONE:
1869 return ECORE_CON_SSL_ERROR_NONE;
1870
1871 case ECORE_CON_SSL_STATE_INIT:
1872 SSL_ERROR_CHECK_GOTO_ERROR(!(cl->ssl = SSL_new(cl->host_server->ssl_ctx)));
1873
1874 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(cl->ssl, cl->fd));
1875 SSL_set_accept_state(cl->ssl);
1876 cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1877
1878 case ECORE_CON_SSL_STATE_HANDSHAKING:
1879 if (!cl->ssl)
1880 {
1881 DBG("Client was previously lost, going to error condition");
1882 goto error;
1883 }
1884 ret = SSL_do_handshake(cl->ssl);
1885 cl->ssl_err = SSL_get_error(cl->ssl, ret);
1886 SSL_ERROR_CHECK_GOTO_ERROR((cl->ssl_err == SSL_ERROR_SYSCALL) || (cl->ssl_err == SSL_ERROR_SSL));
1887 if (ret == 1)
1888 {
1889 cl->handshaking = EINA_FALSE;
1890 cl->ssl_state = ECORE_CON_SSL_STATE_DONE;
1891 }
1892 else
1893 {
1894 if (cl->ssl_err == SSL_ERROR_WANT_READ)
1895 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
1896 else if (cl->ssl_err == SSL_ERROR_WANT_WRITE)
1897 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
1898 return ECORE_CON_SSL_ERROR_NONE;
1899 }
1900
1901 default:
1902 break;
1903 }
1904
1905 _openssl_print_session(cl->ssl);
1906 if (!cl->host_server->verify)
1907 /* not verifying certificates, so we're done! */
1908 return ECORE_CON_SSL_ERROR_NONE;
1909 SSL_set_verify(cl->ssl, SSL_VERIFY_PEER, NULL);
1910 /* use CRL/CA lists to verify */
1911 if (SSL_get_peer_certificate(cl->ssl))
1912 {
1913 int err;
1914
1915 err = SSL_get_verify_result(cl->ssl);
1916 _openssl_print_verify_error(err);
1917 SSL_ERROR_CHECK_GOTO_ERROR(err);
1918 }
1919
1920 return ECORE_CON_SSL_ERROR_NONE;
1921
1922error:
1923 _openssl_print_errors(cl, ECORE_CON_EVENT_CLIENT_ERROR);
1924 _ecore_con_ssl_client_shutdown_openssl(cl);
1925 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
1926}
1927
1928static Ecore_Con_Ssl_Error
1929_ecore_con_ssl_client_shutdown_openssl(Ecore_Con_Client *cl)
1930{
1931 if (cl->ssl)
1932 {
1933 if (!SSL_shutdown(cl->ssl))
1934 SSL_shutdown(cl->ssl);
1935
1936 SSL_free(cl->ssl);
1937 }
1938
1939 cl->ssl = NULL;
1940 cl->ssl_err = SSL_ERROR_NONE;
1941
1942 return ECORE_CON_SSL_ERROR_NONE;
1943}
1944
1945static int
1946_ecore_con_ssl_client_read_openssl(Ecore_Con_Client *cl,
1947 unsigned char *buf,
1948 int size)
1949{
1950 int num;
1951
1952 if (!cl->ssl) return -1;
1953 num = SSL_read(cl->ssl, buf, size);
1954 cl->ssl_err = SSL_get_error(cl->ssl, num);
1955
1956 if (cl->fd_handler)
1957 {
1958 if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ)
1959 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
1960 else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE)
1961 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
1962 }
1963
1964 if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
1965 (cl->ssl_err == SSL_ERROR_SYSCALL) ||
1966 (cl->ssl_err == SSL_ERROR_SSL))
1967 return -1;
1968
1969 if (num < 0)
1970 return 0;
1971
1972 return num;
1973}
1974
1975static int
1976_ecore_con_ssl_client_write_openssl(Ecore_Con_Client *cl,
1977 const unsigned char *buf,
1978 int size)
1979{
1980 int num;
1981
1982 num = SSL_write(cl->ssl, buf, size);
1983 cl->ssl_err = SSL_get_error(cl->ssl, num);
1984
1985 if (cl->fd_handler)
1986 {
1987 if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ)
1988 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
1989 else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE)
1990 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
1991 }
1992
1993 if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
1994 (cl->ssl_err == SSL_ERROR_SYSCALL) ||
1995 (cl->ssl_err == SSL_ERROR_SSL))
1996 return -1;
1997
1998 if (num < 0)
1999 return 0;
2000
2001 return num;
2002}
2003
2004#else
2005
2006/*
2007 * No Ssl
2008 */
2009
2010static Ecore_Con_Ssl_Error
2011_ecore_con_ssl_init_none(void)
2012{
2013 return ECORE_CON_SSL_ERROR_NONE;
2014}
2015
2016static Ecore_Con_Ssl_Error
2017_ecore_con_ssl_shutdown_none(void)
2018{
2019 return ECORE_CON_SSL_ERROR_NONE;
2020}
2021
2022static Ecore_Con_Ssl_Error
2023_ecore_con_ssl_server_prepare_none(Ecore_Con_Server *svr __UNUSED__,
2024 int ssl_type __UNUSED__)
2025{
2026 return ECORE_CON_SSL_ERROR_NONE;
2027}
2028
2029static Ecore_Con_Ssl_Error
2030_ecore_con_ssl_server_init_none(Ecore_Con_Server *svr __UNUSED__)
2031{
2032 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
2033}
2034
2035static Eina_Bool
2036_ecore_con_ssl_server_cafile_add_none(Ecore_Con_Server *svr __UNUSED__,
2037 const char *ca_file __UNUSED__)
2038{
2039 return EINA_FALSE;
2040}
2041
2042static Eina_Bool
2043_ecore_con_ssl_server_cert_add_none(Ecore_Con_Server *svr __UNUSED__,
2044 const char *cert_file __UNUSED__)
2045{
2046 return EINA_FALSE;
2047}
2048
2049static Eina_Bool
2050_ecore_con_ssl_server_privkey_add_none(Ecore_Con_Server *svr __UNUSED__,
2051 const char *key_file __UNUSED__)
2052{
2053 return EINA_FALSE;
2054}
2055
2056static Eina_Bool
2057_ecore_con_ssl_server_crl_add_none(Ecore_Con_Server *svr __UNUSED__,
2058 const char *crl_file __UNUSED__)
2059{
2060 return EINA_FALSE;
2061}
2062
2063static Ecore_Con_Ssl_Error
2064_ecore_con_ssl_server_shutdown_none(Ecore_Con_Server *svr __UNUSED__)
2065{
2066 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
2067}
2068
2069static int
2070_ecore_con_ssl_server_read_none(Ecore_Con_Server *svr __UNUSED__,
2071 unsigned char *buf __UNUSED__,
2072 int size __UNUSED__)
2073{
2074 return -1;
2075}
2076
2077static int
2078_ecore_con_ssl_server_write_none(Ecore_Con_Server *svr __UNUSED__,
2079 const unsigned char *buf __UNUSED__,
2080 int size __UNUSED__)
2081{
2082 return -1;
2083}
2084
2085static Ecore_Con_Ssl_Error
2086_ecore_con_ssl_client_init_none(Ecore_Con_Client *cl __UNUSED__)
2087{
2088 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
2089}
2090
2091static Ecore_Con_Ssl_Error
2092_ecore_con_ssl_client_shutdown_none(Ecore_Con_Client *cl __UNUSED__)
2093{
2094 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
2095}
2096
2097static int
2098_ecore_con_ssl_client_read_none(Ecore_Con_Client *cl __UNUSED__,
2099 unsigned char *buf __UNUSED__,
2100 int size __UNUSED__)
2101{
2102 return -1;
2103}
2104
2105static int
2106_ecore_con_ssl_client_write_none(Ecore_Con_Client *cl __UNUSED__,
2107 const unsigned char *buf __UNUSED__,
2108 int size __UNUSED__)
2109{
2110 return -1;
2111}
2112
2113#endif