#include <gnutls_state.h>
#ifdef HANDSHAKE_DEBUG
-#define ERR(x, y) _gnutls_handshake_log( "HSK: %s (%d)\n", x,y)
+#define ERR(x, y) _gnutls_handshake_log( "HSK[%x]: %s (%d)\n", session, x,y)
#else
#define ERR(x, y)
#endif
}
DECR_LEN(len, 2);
- _gnutls_handshake_log("HSK: Client's version: %d.%d\n", data[pos], data[pos + 1]);
+ _gnutls_handshake_log("HSK[%x]: Client's version: %d.%d\n", session, data[pos], data[pos + 1]);
version = _gnutls_version_get(data[pos], data[pos + 1]);
set_adv_version(session, data[pos], data[pos + 1]);
}
#ifdef HANDSHAKE_DEBUG
- _gnutls_handshake_log("HSK: Requested cipher suites: \n");
+ _gnutls_handshake_log("HSK[%x]: Requested cipher suites: \n", session);
for (j = 0; j < datalen; j += 2)
_gnutls_handshake_log("\t%s\n",
_gnutls_cipher_suite_get_name(*
((GNUTLS_CipherSuite *) & data[j])));
- _gnutls_handshake_log("HSK: Supported cipher suites: \n");
+ _gnutls_handshake_log("HSK[%x]: Supported cipher suites: \n", session);
for (j = 0; j < x; j++)
_gnutls_handshake_log("\t%s\n",
_gnutls_cipher_suite_get_name(ciphers[j]));
for (i = 0; i < x; i++) {
if (memcmp(ciphers[i].CipherSuite, &data[j], 2) ==
0) {
- _gnutls_handshake_log("HSK: Selected cipher suite: %s\n",
- _gnutls_cipher_suite_get_name(*
+ _gnutls_handshake_log("HSK[%x]: Selected cipher suite: %s\n",
+ session, _gnutls_cipher_suite_get_name(*
((GNUTLS_CipherSuite *) & data[j])));
memcpy(session->security_parameters.current_cipher_suite.CipherSuite, ciphers[i].CipherSuite, 2);
retval = 0;
if (session->internals.auth_struct == NULL) {
_gnutls_handshake_log
- ("HSK: Cannot find the appropriate handler for the KX algorithm\n");
+ ("HSK[%x]: Cannot find the appropriate handler for the KX algorithm\n", session);
gnutls_assert();
return GNUTLS_E_INTERNAL_ERROR;
}
session->internals.compression_method = method;
gnutls_free(comps);
- _gnutls_handshake_log("HSK: Selected Compression Method: %s\n",
- gnutls_compression_get_name(session->internals.
+ _gnutls_handshake_log("HSK[%x]: Selected Compression Method: %s\n",
+ session, gnutls_compression_get_name(session->internals.
compression_method));
if (i_datasize > 0)
memcpy(&data[pos], i_data, i_datasize);
- _gnutls_handshake_log("HSK: %s was send [%ld bytes]\n",
- _gnutls_handshake2str(type), datasize);
+ _gnutls_handshake_log("HSK[%x]: %s was send [%ld bytes]\n",
+ session, _gnutls_handshake2str(type), datasize);
/* Here we keep the handshake messages in order to hash them...
length32 = _gnutls_read_uint24(&dataptr[1]);
handshake_header_size = HANDSHAKE_HEADER_SIZE;
- _gnutls_handshake_log("HSK: %s was received [%ld bytes]\n",
- _gnutls_handshake2str(dataptr[0]),
+ _gnutls_handshake_log("HSK[%x]: %s was received [%ld bytes]\n",
+ session, _gnutls_handshake2str(dataptr[0]),
length32 + HANDSHAKE_HEADER_SIZE);
} else { /* v2 hello */
*recv_type = dataptr[0];
- _gnutls_handshake_log("HSK: %s(v2) was received [%ld bytes]\n",
- _gnutls_handshake2str(*recv_type),
+ _gnutls_handshake_log("HSK[%x]: %s(v2) was received [%ld bytes]\n",
+ session, _gnutls_handshake2str(*recv_type),
length32 + handshake_header_size);
if (*recv_type != GNUTLS_CLIENT_HELLO) { /* it should be one or nothing */
memcpy(session->security_parameters.
current_cipher_suite.CipherSuite, suite, 2);
- _gnutls_handshake_log("HSK: Selected cipher suite: ");
+ _gnutls_handshake_log("HSK[%x]: Selected cipher suite: ", session);
_gnutls_handshake_log("%s\n",
_gnutls_cipher_suite_get_name(session->
security_parameters.
if (session->internals.auth_struct == NULL) {
_gnutls_handshake_log
- ("HSK: Cannot find the appropriate handler for the KX algorithm\n");
+ ("HSK[%x]: Cannot find the appropriate handler for the KX algorithm\n", session);
gnutls_assert();
return GNUTLS_E_INTERNAL_ERROR;
}
opaque * session_id,
int session_id_len)
{
-char buf[64];
+char buf[2*TLS_MAX_SESSION_ID_SIZE+1];
- _gnutls_handshake_log("HSK: SessionID length: %d\n", session_id_len);
- _gnutls_handshake_log("HSK: SessionID: %s\n",
+ _gnutls_handshake_log("HSK[%x]: SessionID length: %d\n", session, session_id_len);
+ _gnutls_handshake_log("HSK[%x]: SessionID: %s\n", session,
_gnutls_bin2hex(session_id, session_id_len, buf, sizeof(buf)));
if ((session->internals.resumed_security_parameters.
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
- _gnutls_handshake_log("HSK: Server's version: %d.%d\n", data[pos], data[pos + 1]);
+ _gnutls_handshake_log("HSK[%x]: Server's version: %d.%d\n",
+ session, data[pos], data[pos + 1]);
DECR_LEN(len, 2);
version = _gnutls_version_get(data[pos], data[pos + 1]);
uint8 comp;
opaque *SessionID = session->security_parameters.session_id;
uint8 session_id_len = session->security_parameters.session_id_size;
- char buf[64];
+ char buf[2*TLS_MAX_SESSION_ID_SIZE+1];
if (SessionID == NULL)
session_id_len = 0;
}
pos += session_id_len;
- _gnutls_handshake_log("HSK: SessionID: %s\n",
+ _gnutls_handshake_log("HSK[%x]: SessionID: %s\n", session,
_gnutls_bin2hex(SessionID, session_id_len, buf, sizeof(buf)));
memcpy(&data[pos],
* if the client has asked to resume a session, but the server couldn't,
* then a full handshake will be performed.
*
- * In a handshake all kind of errors should be considered as fatal
- * except for the non-fatal errors GNUTLS_E_AGAIN and
- * GNUTLS_E_INTERRUPTED; in that case you may resume the handshake
- * (call this function again, until it returns ok); cf.
+ * The non-fatal errors such as GNUTLS_E_AGAIN and GNUTLS_E_INTERRUPTED
+ * interrupt the handshake procedure, which should be later be resumed.
+ * (call this function again, until it returns 0); cf.
* gnutls_record_get_direction().
*
* If this function is called by a server after a rehandshake request then
if (session->internals.resumed_security_parameters.
session_id_size > 0)
- _gnutls_handshake_log("HSK: Ask to resume: %s\n",
+ _gnutls_handshake_log("HSK[%x]: Ask to resume: %s\n", session,
_gnutls_bin2hex(session->internals.
resumed_security_parameters.
session_id,
int _gnutls_generate_session_id(char *session_id, uint8 * len)
{
- char buf[64];
-
- *len = TLS_RANDOM_SIZE;
+ *len = TLS_MAX_SESSION_ID_SIZE;
if (_gnutls_get_random(session_id, *len, GNUTLS_WEAK_RANDOM) <
0) {
return GNUTLS_E_MEMORY_ERROR;
}
- _gnutls_handshake_log("HSK: Generated SessionID: %s\n",
- _gnutls_bin2hex(session_id, *len, buf, sizeof(buf)));
-
return 0;
}
if (keep == 0) {
- _gnutls_handshake_log("HSK: Keeping ciphersuite: ");
- _gnutls_handshake_log("%s\n",
+ _gnutls_handshake_log("HSK[%x]: Keeping ciphersuite: %s\n", session,
_gnutls_cipher_suite_get_name(*
((GNUTLS_CipherSuite *) & (*cipherSuites)[i].CipherSuite)));
(*cipherSuites)[i].CipherSuite, 2);
newSuiteSize++;
} else {
- _gnutls_handshake_log("HSK: Removing ciphersuite: ");
- _gnutls_handshake_log("%s\n",
+ _gnutls_handshake_log("HSK[%x]: Removing ciphersuite: %s\n", session,
_gnutls_cipher_suite_get_name(*
((GNUTLS_CipherSuite *) & (*cipherSuites)[i].CipherSuite)));
int protocol_priority[16] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
int kx_priority[16] =
{ GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP,
- /* Do not use anonymous authentication, unless you know what that means */
- GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA_EXPORT, 0
+ /* Do not use anonymous authentication, unless you know what that means */
+ GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA_EXPORT, 0
};
int cipher_priority[16] =
{ GNUTLS_CIPHER_ARCFOUR_128, GNUTLS_CIPHER_RIJNDAEL_128_CBC,
- GNUTLS_CIPHER_3DES_CBC,
- GNUTLS_CIPHER_ARCFOUR_40, 0
+ GNUTLS_CIPHER_3DES_CBC,
+ GNUTLS_CIPHER_ARCFOUR_40, 0
};
int comp_priority[16] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 };
int mac_priority[16] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };
/* prototypes */
typedef struct {
- int fd;
- gnutls_session session;
- int secure;
+ int fd;
+ gnutls_session session;
+ int secure;
} socket_st;
ssize_t socket_recv(socket_st socket, void *buffer, int buffer_size);
ssize_t socket_send(socket_st socket, void *buffer, int buffer_size);
-void socket_bye(socket_st *socket);
-void check_rehandshake(socket_st socket, int ret);
-void check_alert(socket_st socket, int ret);
-int do_handshake(socket_st *socket);
-void init_global_tls_stuff(void);
+void socket_bye(socket_st * socket);
+static void check_rehandshake(socket_st socket, int ret);
+static int do_handshake(socket_st * socket);
+static void init_global_tls_stuff(void);
#define MAX(X,Y) (X >= Y ? X : Y);
/* A callback function to be used at the certificate selection time.
*/
-static int cert_callback( gnutls_session session, const gnutls_datum* client_certs,
- int client_certs_num, const gnutls_datum * req_ca_rdn, int nreqs)
+static int cert_callback(gnutls_session session,
+ const gnutls_datum * client_certs,
+ int client_certs_num,
+ const gnutls_datum * req_ca_rdn, int nreqs)
{
-char issuer_dn[256];
-int len, i, ret;
+ char issuer_dn[256];
+ int len, i, ret;
/* Print the server's trusted CAs
*/
if (nreqs > 0)
printf("- Server's trusted authorities:\n");
else
- printf("- Server did not send us any trusted authorities names.\n");
+ printf
+ ("- Server did not send us any trusted authorities names.\n");
+// gnutls_alert_send(session, GNUTLS_AL_WARNING, GNUTLS_A_BAD_CERTIFICATE);
/* print the names (if any) */
- for (i=0;i<nreqs;i++) {
+ for (i = 0; i < nreqs; i++) {
len = sizeof(issuer_dn);
- ret = gnutls_x509_rdn_get( &req_ca_rdn[i], issuer_dn, &len);
- if ( ret >= 0) {
+ ret = gnutls_x509_rdn_get(&req_ca_rdn[i], issuer_dn, &len);
+ if (ret >= 0) {
printf(" [%d]: ", i);
printf("%s\n", issuer_dn);
}
}
if (client_certs_num > 0)
- return 0; /* use the first one */
+ return 0; /* use the first one */
return -1;
/* initializes a gnutls_session with some defaults.
*/
-static gnutls_session init_tls_session( const char* hostname)
+static gnutls_session init_tls_session(const char *hostname)
{
- gnutls_session session;
+ gnutls_session session;
- gnutls_init(&session, GNUTLS_CLIENT);
+ gnutls_init(&session, GNUTLS_CLIENT);
- /* allow the use of private ciphersuites.
- */
- if (disable_extensions == 0)
- gnutls_handshake_set_private_extensions(session, 1);
-
- if (disable_extensions == 0)
- gnutls_server_name_set( session, GNUTLS_NAME_DNS, hostname, strlen(hostname));
-
- gnutls_cipher_set_priority(session, cipher_priority);
- gnutls_compression_set_priority(session, comp_priority);
- gnutls_kx_set_priority(session, kx_priority);
- gnutls_protocol_set_priority(session, protocol_priority);
- gnutls_mac_set_priority(session, mac_priority);
- gnutls_certificate_type_set_priority(session, cert_type_priority);
-
- gnutls_dh_set_prime_bits(session, 512);
-
- gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred);
- gnutls_credentials_set(session, GNUTLS_CRD_SRP, srp_cred);
- gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
-
- gnutls_certificate_client_set_select_function( session, cert_callback);
-
- /* send the fingerprint */
- if (fingerprint != 0)
- gnutls_openpgp_send_key(session, GNUTLS_OPENPGP_KEY_FINGERPRINT);
-
- /* use the max record size extension */
- if (record_max_size > 0 && disable_extensions == 0) {
- if (gnutls_record_set_max_size(session, record_max_size) < 0) {
- fprintf(stderr,
- "Cannot set the maximum record size to %d.\n",
- record_max_size);
- exit(1);
- }
- }
+ /* allow the use of private ciphersuites.
+ */
+ if (disable_extensions == 0)
+ gnutls_handshake_set_private_extensions(session, 1);
+
+ if (disable_extensions == 0)
+ gnutls_server_name_set(session, GNUTLS_NAME_DNS, hostname,
+ strlen(hostname));
+
+ gnutls_cipher_set_priority(session, cipher_priority);
+ gnutls_compression_set_priority(session, comp_priority);
+ gnutls_kx_set_priority(session, kx_priority);
+ gnutls_protocol_set_priority(session, protocol_priority);
+ gnutls_mac_set_priority(session, mac_priority);
+ gnutls_certificate_type_set_priority(session, cert_type_priority);
+
+ gnutls_dh_set_prime_bits(session, 512);
+
+ gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred);
+ gnutls_credentials_set(session, GNUTLS_CRD_SRP, srp_cred);
+ gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
+
+ gnutls_certificate_client_set_select_function(session,
+ cert_callback);
+
+ /* send the fingerprint */
+ if (fingerprint != 0)
+ gnutls_openpgp_send_key(session,
+ GNUTLS_OPENPGP_KEY_FINGERPRINT);
+
+ /* use the max record size extension */
+ if (record_max_size > 0 && disable_extensions == 0) {
+ if (gnutls_record_set_max_size(session, record_max_size) <
+ 0) {
+ fprintf(stderr,
+ "Cannot set the maximum record size to %d.\n",
+ record_max_size);
+ exit(1);
+ }
+ }
- return session;
+ return session;
}
static void gaa_parser(int argc, char **argv);
/* Returns zero if the error code was successfully handled.
*/
-static int handle_error( socket_st hd, int err)
+static int handle_error(socket_st hd, int err)
{
-int alert, ret;
-const char* err_type;
+ int alert, ret;
+ const char *err_type;
+
+ if (err >= 0) return 0;
- if (gnutls_error_is_fatal(err) == 0) {
- ret = 0;
- err_type = "Non fatal";
- } else {
- ret = err;
- err_type = "Fatal";
- }
+ if (gnutls_error_is_fatal(err) == 0) {
+ ret = 0;
+ err_type = "Non fatal";
+ } else {
+ ret = err;
+ err_type = "Fatal";
+ }
fprintf(stderr,
"*** %s error: %s\n", err_type, gnutls_strerror(err));
- if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
- || err == GNUTLS_E_FATAL_ALERT_RECEIVED) {
- alert = gnutls_alert_get(hd.session);
- printf("*** Received alert [%d]: %s\n",
- alert, gnutls_alert_get_name(alert));
- }
-
- return ret;
+ if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
+ || err == GNUTLS_E_FATAL_ALERT_RECEIVED) {
+ alert = gnutls_alert_get(hd.session);
+ printf("*** Received alert [%d]: %s\n",
+ alert, gnutls_alert_get_name(alert));
+
+ }
+
+ check_rehandshake(hd, ret);
+
+ return ret;
}
int main(int argc, char **argv)
{
- int err, ret;
- int sd, ii, i;
- struct sockaddr_in sa;
- char buffer[MAX_BUF + 1];
- char *session_data = NULL;
- char *session_id = NULL;
- int session_data_size;
- int session_id_size;
- fd_set rset;
- int maxfd;
- struct timeval tv;
- int user_term = 0;
- struct hostent *server_host;
- socket_st hd;
+ int err, ret;
+ int sd, ii, i;
+ struct sockaddr_in sa;
+ char buffer[MAX_BUF + 1];
+ char *session_data = NULL;
+ char *session_id = NULL;
+ int session_data_size;
+ int session_id_size;
+ fd_set rset;
+ int maxfd;
+ struct timeval tv;
+ int user_term = 0;
+ struct hostent *server_host;
+ socket_st hd;
+
+ gaa_parser(argc, argv);
+
+ signal(SIGPIPE, SIG_IGN);
+
+ init_global_tls_stuff();
+
+
+ printf("Resolving '%s'...\n", hostname);
+ /* get server name */
+ server_host = gethostbyname(hostname);
+ if (server_host == NULL) {
+ fprintf(stderr, "Cannot resolve %s\n", hostname);
+ exit(1);
+ }
+
+ sd = socket(AF_INET, SOCK_STREAM, 0);
+ ERR(sd, "socket");
+
+ memset(&sa, '\0', sizeof(sa));
+ sa.sin_family = AF_INET;
+ sa.sin_port = htons(port);
+
+ sa.sin_addr.s_addr = *((unsigned int *) server_host->h_addr);
+
+ inet_ntop(AF_INET, &sa.sin_addr, buffer, MAX_BUF);
+ fprintf(stderr, "Connecting to '%s:%d'...\n", buffer, port);
+
+ err = connect(sd, (SA *) & sa, sizeof(sa));
+ ERR(err, "connect");
+
+ hd.secure = 0;
+ hd.fd = sd;
- gaa_parser(argc, argv);
+ hd.session = init_tls_session(hostname);
+ if (starttls)
+ goto after_handshake;
- signal(SIGPIPE, SIG_IGN);
+ for (i = 0; i < 2; i++) {
- init_global_tls_stuff();
+ if (i == 1) {
+ hd.session = init_tls_session(hostname);
+ gnutls_session_set_data(hd.session, session_data,
+ session_data_size);
+ free(session_data);
+ }
+
+ ret = do_handshake(&hd);
+
+ /* Note that every error on handshake is fatal.
+ */
+ if (ret < 0) {
+ fprintf(stderr, "*** Handshake has failed\n");
+ gnutls_perror(ret);
+ gnutls_deinit(hd.session);
+ return 1;
+ } else {
+ printf("- Handshake was completed\n");
+ if (gnutls_session_is_resumed(hd.session) != 0)
+ printf("*** This is a resumed session\n");
+ }
+
+
+
+ if (resume != 0 && i == 0) {
- printf("Resolving '%s'...\n", hostname);
- /* get server name */
- server_host = gethostbyname(hostname);
- if (server_host == NULL) {
- fprintf(stderr, "Cannot resolve %s\n", hostname);
- exit(1);
- }
+ gnutls_session_get_data(hd.session, NULL,
+ &session_data_size);
+ session_data = malloc(session_data_size);
- sd = socket(AF_INET, SOCK_STREAM, 0);
- ERR(sd, "socket");
+ gnutls_session_get_data(hd.session, session_data,
+ &session_data_size);
- memset(&sa, '\0', sizeof(sa));
- sa.sin_family = AF_INET;
- sa.sin_port = htons(port);
+ gnutls_session_get_id(hd.session, NULL,
+ &session_id_size);
+ session_id = malloc(session_id_size);
+ gnutls_session_get_id(hd.session, session_id,
+ &session_id_size);
- sa.sin_addr.s_addr = *((unsigned int *) server_host->h_addr);
+ /* print some information */
+ print_info(hd.session);
- inet_ntop(AF_INET, &sa.sin_addr, buffer, MAX_BUF);
- fprintf(stderr, "Connecting to '%s:%d'...\n", buffer, port);
-
- err = connect(sd, (SA *) & sa, sizeof(sa));
- ERR(err, "connect");
-
- hd.secure = 0;
- hd.fd = sd;
-
- hd.session = init_tls_session(hostname);
- if (starttls)
- goto after_handshake;
-
- for (i = 0; i < 2; i++) {
-
-
- if (i == 1) {
- hd.session = init_tls_session(hostname);
- gnutls_session_set_data(hd.session, session_data,
- session_data_size);
- free(session_data);
- }
-
- ret = do_handshake(&hd);
-
- /* Note that every error on handshake is fatal.
- */
- if ( ret < 0) {
- handle_error(hd, ret);
- fprintf(stderr, "*** Handshake has failed\n");
- gnutls_perror(ret);
- gnutls_deinit(hd.session);
- return 1;
- } else {
- printf("- Handshake was completed\n");
- if (gnutls_session_is_resumed(hd.session) != 0)
- printf("*** This is a resumed session\n");
- }
-
-
-
- if (resume != 0 && i == 0) {
-
- gnutls_session_get_data(hd.session, NULL, &session_data_size);
- session_data = malloc(session_data_size);
-
- gnutls_session_get_data(hd.session, session_data,
- &session_data_size);
-
- gnutls_session_get_id(hd.session, NULL, &session_id_size);
- session_id = malloc(session_id_size);
- gnutls_session_get_id(hd.session, session_id, &session_id_size);
-
- /* print some information */
- print_info(hd.session);
-
- printf("- Disconnecting\n");
- socket_bye(&hd);
-
- printf
- ("\n\n- Connecting again- trying to resume previous session\n");
- sd = socket(AF_INET, SOCK_STREAM, 0);
- ERR(sd, "socket");
-
- err = connect(sd, (SA *) & sa, sizeof(sa));
- ERR(err, "connect");
-
- hd.fd = sd;
- hd.secure = 0;
- } else {
- break;
- }
- }
-
-
- after_handshake:
-
- printf("\n- Simple Client Mode:\n\n");
-
- FD_ZERO(&rset);
- for (;;) {
- FD_SET(fileno(stdin), &rset);
- FD_SET(sd, &rset);
-
- maxfd = MAX(fileno(stdin), sd);
- tv.tv_sec = 3;
- tv.tv_usec = 0;
- select(maxfd + 1, &rset, NULL, NULL, &tv);
-
- if (FD_ISSET(sd, &rset)) {
- bzero(buffer, MAX_BUF + 1);
- ret = socket_recv(hd, buffer, MAX_BUF);
-
- if (ret == 0) {
- printf("- Peer has closed the GNUTLS connection\n");
- break;
- } else if (handle_error(hd, ret) < 0 && user_term == 0) {
- fprintf(stderr,
- "*** Server has terminated the connection abnormally.\n");
- break;
- } else if (ret > 0) {
- if (quiet != 0)
- printf("- Received[%d]: ", ret);
- for (ii = 0; ii < ret; ii++) {
- fputc(buffer[ii], stdout);
- }
- fflush(stdout);
- }
-
- if (user_term != 0)
- break;
- }
-
- if (FD_ISSET(fileno(stdin), &rset)) {
- if (fgets(buffer, MAX_BUF, stdin) == NULL) {
- if (hd.secure == 0) {
- fprintf(stderr, "*** Starting TLS handshake\n");
- ret = do_handshake(&hd);
- if (handle_error(hd, ret) < 0) {
- fprintf(stderr, "*** Handshake has failed\n");
- socket_bye(&hd);
- user_term = 1;
- }
- continue;
- } else {
- user_term = 1;
- continue;
- }
- }
-
- if (crlf != 0) {
- char *b = strchr(buffer, '\n');
- if (b != NULL)
- strcpy(b, "\r\n");
- }
-
- ret = socket_send(hd, buffer, strlen(buffer));
-
- if (ret > 0) {
- if (quiet != 0)
- printf("- Sent: %d bytes\n", ret);
- } else
- handle_error(hd, ret);
-
- }
- }
-
- if (user_term != 0)
- socket_bye(&hd);
+ printf("- Disconnecting\n");
+ socket_bye(&hd);
+
+ printf
+ ("\n\n- Connecting again- trying to resume previous session\n");
+ sd = socket(AF_INET, SOCK_STREAM, 0);
+ ERR(sd, "socket");
+
+ err = connect(sd, (SA *) & sa, sizeof(sa));
+ ERR(err, "connect");
+
+ hd.fd = sd;
+ hd.secure = 0;
+ } else {
+ break;
+ }
+ }
+
+
+ after_handshake:
+
+ printf("\n- Simple Client Mode:\n\n");
+
+ FD_ZERO(&rset);
+ for (;;) {
+ FD_SET(fileno(stdin), &rset);
+ FD_SET(sd, &rset);
+
+ maxfd = MAX(fileno(stdin), sd);
+ tv.tv_sec = 3;
+ tv.tv_usec = 0;
+ select(maxfd + 1, &rset, NULL, NULL, &tv);
+
+ if (FD_ISSET(sd, &rset)) {
+ bzero(buffer, MAX_BUF + 1);
+ ret = socket_recv(hd, buffer, MAX_BUF);
+
+ if (ret == 0) {
+ printf
+ ("- Peer has closed the GNUTLS connection\n");
+ break;
+ } else if (handle_error(hd, ret) < 0
+ && user_term == 0) {
+ fprintf(stderr,
+ "*** Server has terminated the connection abnormally.\n");
+ break;
+ } else if (ret > 0) {
+ if (quiet != 0)
+ printf("- Received[%d]: ", ret);
+ for (ii = 0; ii < ret; ii++) {
+ fputc(buffer[ii], stdout);
+ }
+ fflush(stdout);
+ }
+
+ if (user_term != 0)
+ break;
+ }
+
+ if (FD_ISSET(fileno(stdin), &rset)) {
+ if (fgets(buffer, MAX_BUF, stdin) == NULL) {
+ if (hd.secure == 0) {
+ fprintf(stderr,
+ "*** Starting TLS handshake\n");
+ ret = do_handshake(&hd);
+ if (ret < 0) {
+ fprintf(stderr,
+ "*** Handshake has failed\n");
+ socket_bye(&hd);
+ user_term = 1;
+ }
+ continue;
+ } else {
+ user_term = 1;
+ continue;
+ }
+ }
+
+ if (crlf != 0) {
+ char *b = strchr(buffer, '\n');
+ if (b != NULL)
+ strcpy(b, "\r\n");
+ }
+
+ ret = socket_send(hd, buffer, strlen(buffer));
+
+ if (ret > 0) {
+ if (quiet != 0)
+ printf("- Sent: %d bytes\n", ret);
+ } else
+ handle_error(hd, ret);
+
+ }
+ }
+
+ if (user_term != 0)
+ socket_bye(&hd);
#ifdef ENABLE_SRP
- gnutls_srp_free_client_credentials(srp_cred);
+ gnutls_srp_free_client_credentials(srp_cred);
#endif
- gnutls_certificate_free_credentials(xcred);
+ gnutls_certificate_free_credentials(xcred);
#ifdef ENABLE_ANON
- gnutls_anon_free_client_credentials(anon_cred);
+ gnutls_anon_free_client_credentials(anon_cred);
#endif
- gnutls_global_deinit();
+ gnutls_global_deinit();
- return 0;
+ return 0;
}
static gaainfo info;
void gaa_parser(int argc, char **argv)
{
- if (gaa(argc, argv, &info) != -1) {
- fprintf(stderr,
- "Error in the arguments. Use the --help or -h parameters to get more information.\n");
- exit(1);
- }
-
- debug = info.debug;
- disable_extensions = info.disable_extensions;
- xml = info.xml;
- starttls = info.starttls;
- resume = info.resume;
- port = info.port;
- record_max_size = info.record_size;
- fingerprint = info.fingerprint;
-
- if (info.fmtder == 0)
- x509ctype = GNUTLS_X509_FMT_PEM;
- else
- x509ctype = GNUTLS_X509_FMT_DER;
-
- srp_username = info.srp_username;
- srp_passwd = info.srp_passwd;
- x509_cafile = info.x509_cafile;
- x509_crlfile = info.x509_crlfile;
- x509_keyfile = info.x509_keyfile;
- x509_certfile = info.x509_certfile;
- pgp_keyfile = info.pgp_keyfile;
- pgp_certfile = info.pgp_certfile;
-
- pgp_keyring = info.pgp_keyring;
- pgp_trustdb = info.pgp_trustdb;
-
- crlf = info.crlf;
-
- if (info.rest_args == NULL)
- hostname = "localhost";
- else
- hostname = info.rest_args;
-
- parse_protocols( info.proto, info.nproto, protocol_priority);
- parse_ciphers( info.ciphers, info.nciphers, cipher_priority);
- parse_macs( info.macs, info.nmacs, mac_priority);
- parse_ctypes( info.ctype, info.nctype, cert_type_priority);
- parse_kx( info.kx, info.nkx, kx_priority);
- parse_comp( info.comp, info.ncomp, comp_priority);
+ if (gaa(argc, argv, &info) != -1) {
+ fprintf(stderr,
+ "Error in the arguments. Use the --help or -h parameters to get more information.\n");
+ exit(1);
+ }
+
+ debug = info.debug;
+ disable_extensions = info.disable_extensions;
+ xml = info.xml;
+ starttls = info.starttls;
+ resume = info.resume;
+ port = info.port;
+ record_max_size = info.record_size;
+ fingerprint = info.fingerprint;
+
+ if (info.fmtder == 0)
+ x509ctype = GNUTLS_X509_FMT_PEM;
+ else
+ x509ctype = GNUTLS_X509_FMT_DER;
+
+ srp_username = info.srp_username;
+ srp_passwd = info.srp_passwd;
+ x509_cafile = info.x509_cafile;
+ x509_crlfile = info.x509_crlfile;
+ x509_keyfile = info.x509_keyfile;
+ x509_certfile = info.x509_certfile;
+ pgp_keyfile = info.pgp_keyfile;
+ pgp_certfile = info.pgp_certfile;
+
+ pgp_keyring = info.pgp_keyring;
+ pgp_trustdb = info.pgp_trustdb;
+
+ crlf = info.crlf;
+
+ if (info.rest_args == NULL)
+ hostname = "localhost";
+ else
+ hostname = info.rest_args;
+
+ parse_protocols(info.proto, info.nproto, protocol_priority);
+ parse_ciphers(info.ciphers, info.nciphers, cipher_priority);
+ parse_macs(info.macs, info.nmacs, mac_priority);
+ parse_ctypes(info.ctype, info.nctype, cert_type_priority);
+ parse_kx(info.kx, info.nkx, kx_priority);
+ parse_comp(info.comp, info.ncomp, comp_priority);
}
void cli_version(void)
{
- fprintf(stderr, "GNU TLS test client, ");
- fprintf(stderr, "version %s. Libgnutls %s.\n", LIBGNUTLS_VERSION, gnutls_check_version(NULL));
+ fprintf(stderr, "GNU TLS test client, ");
+ fprintf(stderr, "version %s. Libgnutls %s.\n", LIBGNUTLS_VERSION,
+ gnutls_check_version(NULL));
}
ssize_t socket_recv(socket_st socket, void *buffer, int buffer_size)
{
- int ret;
-
- if (socket.secure)
- do {
- ret = gnutls_record_recv(socket.session, buffer, buffer_size);
- } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
- else
- do {
- ret = recv(socket.fd, buffer, buffer_size, 0);
- } while (ret == -1 && errno == EINTR);
-
- return ret;
+ int ret;
+
+ if (socket.secure)
+ do {
+ ret =
+ gnutls_record_recv(socket.session, buffer,
+ buffer_size);
+ } while (ret == GNUTLS_E_INTERRUPTED
+ || ret == GNUTLS_E_AGAIN);
+ else
+ do {
+ ret = recv(socket.fd, buffer, buffer_size, 0);
+ } while (ret == -1 && errno == EINTR);
+
+ return ret;
}
ssize_t socket_send(socket_st socket, void *buffer, int buffer_size)
{
- int ret;
-
- if (socket.secure)
- do {
- ret = gnutls_record_send(socket.session, buffer, buffer_size);
- } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
- else
- do {
- ret = send(socket.fd, buffer, buffer_size, 0);
- } while (ret == -1 && errno == EINTR);
+ int ret;
+
+ if (socket.secure)
+ do {
+ ret =
+ gnutls_record_send(socket.session, buffer,
+ buffer_size);
+ } while (ret == GNUTLS_E_AGAIN
+ || ret == GNUTLS_E_INTERRUPTED);
+ else
+ do {
+ ret = send(socket.fd, buffer, buffer_size, 0);
+ } while (ret == -1 && errno == EINTR);
- return ret;
+ return ret;
}
-void socket_bye(socket_st *socket)
+void socket_bye(socket_st * socket)
{
- int ret;
- if (socket->secure) {
- do
- ret = gnutls_bye(socket->session, GNUTLS_SHUT_RDWR);
- while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
- gnutls_deinit(socket->session);
- socket->session = NULL;
- }
-
- shutdown(socket->fd, SHUT_RDWR); /* no more receptions */
- close(socket->fd);
-
- socket->fd = -1;
- socket->secure = 0;
-}
+ int ret;
+ if (socket->secure) {
+ do
+ ret =
+ gnutls_bye(socket->session, GNUTLS_SHUT_RDWR);
+ while (ret == GNUTLS_E_INTERRUPTED
+ || ret == GNUTLS_E_AGAIN);
+ gnutls_deinit(socket->session);
+ socket->session = NULL;
+ }
-void check_rehandshake(socket_st socket, int ret)
-{
- if (socket.secure && ret == GNUTLS_E_REHANDSHAKE) {
- /* There is a race condition here. If application
- * data is sent after the rehandshake request,
- * the server thinks we ignored his request.
- * This is a bad design of this client.
- */
- printf("* Received rehandshake request\n");
- /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */
-
- do {
- ret = gnutls_handshake(socket.session);
- } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
-
- if (ret == 0) {
- printf("* Rehandshake was performed.\n");
- } else {
- handle_error( socket, ret);
- printf("* Rehandshake Failed.\n");
- }
- }
+ shutdown(socket->fd, SHUT_RDWR); /* no more receptions */
+ close(socket->fd);
+
+ socket->fd = -1;
+ socket->secure = 0;
}
-void check_alert(socket_st socket, int ret)
+static void check_rehandshake(socket_st socket, int ret)
{
- if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED
- || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) {
- printf("* Received alert [%d]\n", gnutls_alert_get(socket.session));
-
- check_rehandshake(socket, ret);
- }
+ if (socket.secure && ret == GNUTLS_E_REHANDSHAKE) {
+ /* There is a race condition here. If application
+ * data is sent after the rehandshake request,
+ * the server thinks we ignored his request.
+ * This is a bad design of this client.
+ */
+ printf("* Received rehandshake request\n");
+ /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */
+
+ ret = do_handshake(&socket);
+
+ if (ret == 0) {
+ printf("* Rehandshake was performed.\n");
+ } else {
+ printf("* Rehandshake Failed.\n");
+ }
+ }
}
-int do_handshake(socket_st* socket)
+
+static int do_handshake(socket_st * socket)
{
- int ret;
- gnutls_transport_set_ptr(socket->session,
- (gnutls_transport_ptr)socket->fd);
- do {
- ret = gnutls_handshake(socket->session);
- } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
-
- if (ret==0) {
- socket->secure = 1;
- /* print some information */
- print_info(socket->session);
- }
- return ret;
+ int ret;
+ gnutls_transport_set_ptr(socket->session,
+ (gnutls_transport_ptr) socket->fd);
+ do {
+ ret = gnutls_handshake(socket->session);
+
+ if (ret < 0) {
+ handle_error(*socket, ret);
+ }
+ } while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
+
+ if (ret == 0) {
+ socket->secure = 1;
+ /* print some information */
+ print_info(socket->session);
+ }
+ return ret;
}
-static void tls_log_func( int level, const char* str)
+static void tls_log_func(int level, const char *str)
{
fprintf(stderr, "|<%d>| %s", level, str);
}
-void init_global_tls_stuff()
+static void init_global_tls_stuff()
{
-int ret;
-
- if (gnutls_global_init() < 0) {
- fprintf(stderr, "global state initialization error\n");
- exit(1);
- }
- gnutls_global_set_log_function( tls_log_func);
- gnutls_global_set_log_level(debug);
-
- if (gnutls_global_init_extra() < 0) {
- fprintf(stderr, "global state (extra) initialization error\n");
- exit(1);
- }
-
- /* X509 stuff */
- if (gnutls_certificate_allocate_credentials(&xcred) < 0) {
- fprintf(stderr, "Certificate allocation memory error\n");
- exit(1);
- }
-
- /* there are some intermediate CAs that have a v1 certificate *%&@#*%&
- */
- gnutls_certificate_set_verify_flags( xcred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
-
- if (x509_cafile != NULL) {
- ret =
- gnutls_certificate_set_x509_trust_file(xcred,
- x509_cafile, x509ctype);
- if (ret < 0) {
- fprintf(stderr, "Error setting the x509 trust file\n");
- } else {
- printf("Processed %d CA certificate(s).\n", ret);
- }
- }
+ int ret;
+
+ if (gnutls_global_init() < 0) {
+ fprintf(stderr, "global state initialization error\n");
+ exit(1);
+ }
+ gnutls_global_set_log_function(tls_log_func);
+ gnutls_global_set_log_level(debug);
+
+ if (gnutls_global_init_extra() < 0) {
+ fprintf(stderr,
+ "global state (extra) initialization error\n");
+ exit(1);
+ }
+
+ /* X509 stuff */
+ if (gnutls_certificate_allocate_credentials(&xcred) < 0) {
+ fprintf(stderr, "Certificate allocation memory error\n");
+ exit(1);
+ }
+ /* there are some intermediate CAs that have a v1 certificate *%&@#*%&
+ */
+ gnutls_certificate_set_verify_flags(xcred,
+ GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
+
+ if (x509_cafile != NULL) {
+ ret =
+ gnutls_certificate_set_x509_trust_file(xcred,
+ x509_cafile,
+ x509ctype);
+ if (ret < 0) {
+ fprintf(stderr,
+ "Error setting the x509 trust file\n");
+ } else {
+ printf("Processed %d CA certificate(s).\n", ret);
+ }
+ }
#ifdef ENABLE_PKI
- if (x509_crlfile != NULL) {
- ret =
- gnutls_certificate_set_x509_crl_file(xcred,
- x509_crlfile, x509ctype);
- if (ret < 0) {
- fprintf(stderr, "Error setting the x509 CRL file\n");
- } else {
- printf("Processed %d CRL(s).\n", ret);
- }
- }
+ if (x509_crlfile != NULL) {
+ ret =
+ gnutls_certificate_set_x509_crl_file(xcred,
+ x509_crlfile,
+ x509ctype);
+ if (ret < 0) {
+ fprintf(stderr,
+ "Error setting the x509 CRL file\n");
+ } else {
+ printf("Processed %d CRL(s).\n", ret);
+ }
+ }
#endif
- if (x509_certfile != NULL) {
- ret =
- gnutls_certificate_set_x509_key_file(xcred,
- x509_certfile,
- x509_keyfile, x509ctype);
- if (ret < 0) {
- fprintf(stderr,
- "Error setting the x509 key files ('%s', '%s')\n",
- x509_certfile, x509_keyfile);
- }
- }
-
- if (pgp_certfile != NULL) {
- ret =
- gnutls_certificate_set_openpgp_key_file(xcred,
- pgp_certfile,
- pgp_keyfile);
- if (ret < 0) {
- fprintf(stderr,
- "Error setting the x509 key files ('%s', '%s')\n",
- pgp_certfile, pgp_keyfile);
- }
- }
-
- if (pgp_keyring != NULL) {
- ret =
- gnutls_certificate_set_openpgp_keyring_file(xcred, pgp_keyring);
- if (ret < 0) {
- fprintf(stderr, "Error setting the OpenPGP keyring file\n");
- }
- }
-
- if (pgp_trustdb != NULL) {
- ret = gnutls_certificate_set_openpgp_trustdb(xcred, pgp_trustdb);
- if (ret < 0) {
- fprintf(stderr, "Error setting the OpenPGP trustdb file\n");
- }
- }
+ if (x509_certfile != NULL) {
+ ret =
+ gnutls_certificate_set_x509_key_file(xcred,
+ x509_certfile,
+ x509_keyfile,
+ x509ctype);
+ if (ret < 0) {
+ fprintf(stderr,
+ "Error setting the x509 key files ('%s', '%s')\n",
+ x509_certfile, x509_keyfile);
+ }
+ }
+ if (pgp_certfile != NULL) {
+ ret =
+ gnutls_certificate_set_openpgp_key_file(xcred,
+ pgp_certfile,
+ pgp_keyfile);
+ if (ret < 0) {
+ fprintf(stderr,
+ "Error setting the x509 key files ('%s', '%s')\n",
+ pgp_certfile, pgp_keyfile);
+ }
+ }
+
+ if (pgp_keyring != NULL) {
+ ret =
+ gnutls_certificate_set_openpgp_keyring_file(xcred,
+ pgp_keyring);
+ if (ret < 0) {
+ fprintf(stderr,
+ "Error setting the OpenPGP keyring file\n");
+ }
+ }
+
+ if (pgp_trustdb != NULL) {
+ ret =
+ gnutls_certificate_set_openpgp_trustdb(xcred,
+ pgp_trustdb);
+ if (ret < 0) {
+ fprintf(stderr,
+ "Error setting the OpenPGP trustdb file\n");
+ }
+ }
#ifdef ENABLE_SRP
- /* SRP stuff */
- if (gnutls_srp_allocate_client_credentials(&srp_cred) < 0) {
- fprintf(stderr, "SRP authentication error\n");
- }
-
- if (srp_username != NULL) {
- if ((ret=gnutls_srp_set_client_credentials(srp_cred, srp_username, srp_passwd)) < 0) {
- fprintf(stderr, "SRP credentials set error [%d]\n", ret);
- }
- }
+ /* SRP stuff */
+ if (gnutls_srp_allocate_client_credentials(&srp_cred) < 0) {
+ fprintf(stderr, "SRP authentication error\n");
+ }
+
+ if (srp_username != NULL) {
+ if ((ret =
+ gnutls_srp_set_client_credentials(srp_cred,
+ srp_username,
+ srp_passwd)) < 0) {
+ fprintf(stderr, "SRP credentials set error [%d]\n",
+ ret);
+ }
+ }
#endif
#ifdef ENABLE_ANON
- /* ANON stuff */
- if (gnutls_anon_allocate_client_credentials(&anon_cred) < 0) {
- fprintf(stderr, "Anonymous authentication error\n");
- }
+ /* ANON stuff */
+ if (gnutls_anon_allocate_client_credentials(&anon_cred) < 0) {
+ fprintf(stderr, "Anonymous authentication error\n");
+ }
#endif
}