3 #include <netinet/tcp.h>
4 #include <netinet/in.h>
5 #include <sys/socket.h>
9 #include <gnutls/gnutls.h>
11 /* Ecore_Fd_Handler example
12 * 2010 Mike Blumenkrantz
13 * compile with gcc $(pkgconfig --cflags --libs gnutls ecore)
16 #define print(...) fprintf(stderr, "line %i: ", __LINE__); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n")
21 tls_log_func(int level, const char *str)
23 fprintf(stderr, "|<%d>| %s", level, str);
27 SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_description_t status)
31 case GNUTLS_HANDSHAKE_HELLO_REQUEST:
32 return "Hello request";
34 case GNUTLS_HANDSHAKE_CLIENT_HELLO:
35 return "Client hello";
37 case GNUTLS_HANDSHAKE_SERVER_HELLO:
38 return "Server hello";
40 case GNUTLS_HANDSHAKE_CERTIFICATE_PKT:
41 return "Certificate packet";
43 case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE:
44 return "Server key exchange";
46 case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST:
47 return "Certificate request";
49 case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE:
50 return "Server hello done";
52 case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY:
53 return "Certificate verify";
55 case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
56 return "Client key exchange";
58 case GNUTLS_HANDSHAKE_FINISHED:
61 case GNUTLS_HANDSHAKE_SUPPLEMENTAL:
62 return "Supplemental";
67 /* Connects to the peer and returns a socket
73 const char *PORT = "443";
74 const char *SERVER = "69.58.181.89"; //verisign.com
76 int flag = 1, curstate = 0;
77 struct sockaddr_in sa;
79 /* sets some fd options such as nonblock */
80 sd = socket(AF_INET, SOCK_STREAM, 0);
81 fcntl(sd, F_SETFL, O_NONBLOCK);
82 fcntl(sd, F_SETFD, FD_CLOEXEC);
83 setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate, sizeof(curstate));
85 setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
87 memset(&sa, '\0', sizeof (sa));
88 sa.sin_family = AF_INET;
89 sa.sin_port = htons(atoi(PORT));
90 inet_pton(AF_INET, SERVER, &sa.sin_addr);
94 err = connect(sd, (struct sockaddr *)&sa, sizeof (sa));
95 if ((err < 0) && (errno != EINPROGRESS))
97 print("Connect error\n");
104 /* closes the given socket descriptor.
109 shutdown(sd, SHUT_RDWR); /* no more receptions */
114 _process_data(gnutls_session_t client, Ecore_Fd_Handler *fd_handler)
116 static int ret, lastret;
117 static unsigned int count = 0;
122 ret = gnutls_handshake(client);
124 if (gnutls_record_get_direction(client))
125 ecore_main_fd_handler_active_set(fd_handler, ECORE_FD_WRITE);
127 ecore_main_fd_handler_active_set(fd_handler, ECORE_FD_READ);
128 /* avoid printing messages infinity times */
131 print("gnutls returned with: %s - %s", gnutls_strerror_name(ret), gnutls_strerror(ret));
132 if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED))
133 print("Also received alert: %s", gnutls_alert_get_name(gnutls_alert_get(client)));
134 print("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_out(client)));
135 print("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_in(client)));
138 if (gnutls_error_is_fatal(ret))
140 print("yarrr this be an error!");
144 if (ret == GNUTLS_E_SUCCESS)
147 print("Handshake successful in %u handshake calls!", count);
148 ecore_main_loop_quit();
151 return ECORE_CALLBACK_RENEW;
158 gnutls_anon_client_credentials_t c_anoncred;
159 gnutls_certificate_credentials_t c_certcred;
161 gnutls_session_t client;
165 gnutls_global_init();
167 gnutls_global_set_log_function(tls_log_func);
168 gnutls_global_set_log_level(6);
171 gnutls_anon_allocate_client_credentials(&c_anoncred);
172 gnutls_certificate_allocate_credentials(&c_certcred);
173 gnutls_init(&client, GNUTLS_CLIENT);
174 /* set very specific priorities */
175 gnutls_priority_set_direct(client, "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", NULL);
176 gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred);
177 gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, c_certcred);
178 gnutls_server_name_set(client, GNUTLS_NAME_DNS, "www.verisign.com", strlen("www.verisign.com"));
180 /* connect to the peer
184 /* associate gnutls with socket */
185 gnutls_transport_set_ptr(client, (gnutls_transport_ptr_t)sd);
186 /* add a callback for data being available for send/receive on socket */
187 if (!ecore_main_fd_handler_add(sd, ECORE_FD_READ | ECORE_FD_WRITE, (Ecore_Fd_Cb)_process_data, client, NULL, NULL))
189 print("could not create fd handler!");
192 /* begin main loop */
193 ecore_main_loop_begin();
195 gnutls_bye(client, GNUTLS_SHUT_RDWR);
197 gnutls_deinit(client);