summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2002-10-07 13:38:56 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2002-10-07 13:38:56 +0000
commit2527a7991229bd084c5d43f6d94216f736915706 (patch)
treeb946570b8db454273e2e1afc51f9c3ed8f57a14d
parent857a4dd103f48d90d419da37ce4812512bba904b (diff)
downloadgnutls-2527a7991229bd084c5d43f6d94216f736915706.tar.gz
Changes in gnutls-cli, to allow testing of starttls implementations.
-rw-r--r--src/cli-gaa.c127
-rw-r--r--src/cli-gaa.h58
-rw-r--r--src/cli.c432
-rw-r--r--src/cli.gaa5
4 files changed, 366 insertions, 256 deletions
diff --git a/src/cli-gaa.c b/src/cli-gaa.c
index 33136f98e5..114dbded8c 100644
--- a/src/cli-gaa.c
+++ b/src/cli-gaa.c
@@ -128,6 +128,7 @@ void gaa_help(void)
{
printf("GNU TLS test client\nUsage: gnutls-cli [options] hostname\n\n\n");
__gaa_helpsingle('r', "resume", "", "Connect, establish a session. Connect again and resume this session.");
+ __gaa_helpsingle('s', "starttls", "", "Connect, establish a plain session and start TLS when EOF is sent.");
__gaa_helpsingle(0, "crlf", "", "Send CR LF instead of LF.");
__gaa_helpsingle(0, "x509fmtder", "", "Use DER format for certificates");
__gaa_helpsingle('f', "fingerprint", "", "Send the openpgp fingerprint, instead of the key.");
@@ -166,62 +167,64 @@ typedef struct _gaainfo gaainfo;
struct _gaainfo
{
-#line 92 "cli.gaa"
+#line 95 "cli.gaa"
char **rest_args;
-#line 91 "cli.gaa"
+#line 94 "cli.gaa"
int nrest_args;
-#line 81 "cli.gaa"
+#line 84 "cli.gaa"
char *srp_passwd;
-#line 78 "cli.gaa"
+#line 81 "cli.gaa"
char *srp_username;
-#line 75 "cli.gaa"
+#line 78 "cli.gaa"
char *x509_certfile;
-#line 72 "cli.gaa"
+#line 75 "cli.gaa"
char *x509_keyfile;
-#line 69 "cli.gaa"
+#line 72 "cli.gaa"
char *pgp_certfile;
-#line 66 "cli.gaa"
+#line 69 "cli.gaa"
char *pgp_trustdb;
-#line 63 "cli.gaa"
+#line 66 "cli.gaa"
char *pgp_keyring;
-#line 60 "cli.gaa"
+#line 63 "cli.gaa"
char *pgp_keyfile;
-#line 57 "cli.gaa"
+#line 60 "cli.gaa"
char *x509_cafile;
-#line 54 "cli.gaa"
+#line 57 "cli.gaa"
char **ctype;
-#line 53 "cli.gaa"
+#line 56 "cli.gaa"
int nctype;
-#line 50 "cli.gaa"
+#line 53 "cli.gaa"
char **kx;
-#line 49 "cli.gaa"
+#line 52 "cli.gaa"
int nkx;
-#line 46 "cli.gaa"
+#line 49 "cli.gaa"
char **macs;
-#line 45 "cli.gaa"
+#line 48 "cli.gaa"
int nmacs;
-#line 42 "cli.gaa"
+#line 45 "cli.gaa"
char **comp;
-#line 41 "cli.gaa"
+#line 44 "cli.gaa"
int ncomp;
-#line 38 "cli.gaa"
+#line 41 "cli.gaa"
char **proto;
-#line 37 "cli.gaa"
+#line 40 "cli.gaa"
int nproto;
-#line 34 "cli.gaa"
+#line 37 "cli.gaa"
char **ciphers;
-#line 33 "cli.gaa"
+#line 36 "cli.gaa"
int nciphers;
-#line 29 "cli.gaa"
+#line 32 "cli.gaa"
int record_size;
-#line 26 "cli.gaa"
+#line 29 "cli.gaa"
int port;
-#line 23 "cli.gaa"
+#line 26 "cli.gaa"
int fingerprint;
-#line 20 "cli.gaa"
+#line 23 "cli.gaa"
int fmtder;
-#line 17 "cli.gaa"
+#line 20 "cli.gaa"
int crlf;
+#line 17 "cli.gaa"
+ int starttls;
#line 14 "cli.gaa"
int resume;
@@ -278,7 +281,7 @@ int gaa_error = 0;
#define GAA_MULTIPLE_OPTION 3
#define GAA_REST 0
-#define GAA_NB_OPTION 25
+#define GAA_NB_OPTION 26
#define GAAOPTID_copyright 1
#define GAAOPTID_version 2
#define GAAOPTID_help 3
@@ -303,7 +306,8 @@ int gaa_error = 0;
#define GAAOPTID_fingerprint 22
#define GAAOPTID_x509fmtder 23
#define GAAOPTID_crlf 24
-#define GAAOPTID_resume 25
+#define GAAOPTID_starttls 25
+#define GAAOPTID_resume 26
#line 168 "gaa.skel"
@@ -654,6 +658,7 @@ int gaa_get_option_num(char *str, int status)
GAA_CHECK1STR("f", GAAOPTID_fingerprint);
GAA_CHECK1STR("", GAAOPTID_x509fmtder);
GAA_CHECK1STR("", GAAOPTID_crlf);
+ GAA_CHECK1STR("s", GAAOPTID_starttls);
GAA_CHECK1STR("r", GAAOPTID_resume);
#line 277 "gaa.skel"
@@ -683,6 +688,7 @@ int gaa_get_option_num(char *str, int status)
GAA_CHECKSTR("fingerprint", GAAOPTID_fingerprint);
GAA_CHECKSTR("x509fmtder", GAAOPTID_x509fmtder);
GAA_CHECKSTR("crlf", GAAOPTID_crlf);
+ GAA_CHECKSTR("starttls", GAAOPTID_starttls);
GAA_CHECKSTR("resume", GAAOPTID_resume);
#line 281 "gaa.skel"
@@ -735,28 +741,28 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
{
case GAAOPTID_copyright:
OK = 0;
-#line 89 "cli.gaa"
+#line 92 "cli.gaa"
{ print_license(); exit(0); ;};
return GAA_OK;
break;
case GAAOPTID_version:
OK = 0;
-#line 88 "cli.gaa"
+#line 91 "cli.gaa"
{ cli_version(); exit(0); ;};
return GAA_OK;
break;
case GAAOPTID_help:
OK = 0;
-#line 86 "cli.gaa"
+#line 89 "cli.gaa"
{ gaa_help(); exit(0); ;};
return GAA_OK;
break;
case GAAOPTID_list:
OK = 0;
-#line 85 "cli.gaa"
+#line 88 "cli.gaa"
{ print_list(); exit(0); ;};
return GAA_OK;
@@ -766,7 +772,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_srppasswd.arg1, gaa_getstr, GAATMP_srppasswd.size1);
gaa_index++;
-#line 82 "cli.gaa"
+#line 85 "cli.gaa"
{ gaaval->srp_passwd = GAATMP_srppasswd.arg1 ;};
return GAA_OK;
@@ -776,7 +782,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_srpusername.arg1, gaa_getstr, GAATMP_srpusername.size1);
gaa_index++;
-#line 79 "cli.gaa"
+#line 82 "cli.gaa"
{ gaaval->srp_username = GAATMP_srpusername.arg1 ;};
return GAA_OK;
@@ -786,7 +792,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_x509certfile.arg1, gaa_getstr, GAATMP_x509certfile.size1);
gaa_index++;
-#line 76 "cli.gaa"
+#line 79 "cli.gaa"
{ gaaval->x509_certfile = GAATMP_x509certfile.arg1 ;};
return GAA_OK;
@@ -796,7 +802,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_x509keyfile.arg1, gaa_getstr, GAATMP_x509keyfile.size1);
gaa_index++;
-#line 73 "cli.gaa"
+#line 76 "cli.gaa"
{ gaaval->x509_keyfile = GAATMP_x509keyfile.arg1 ;};
return GAA_OK;
@@ -806,7 +812,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_pgpcertfile.arg1, gaa_getstr, GAATMP_pgpcertfile.size1);
gaa_index++;
-#line 70 "cli.gaa"
+#line 73 "cli.gaa"
{ gaaval->pgp_certfile = GAATMP_pgpcertfile.arg1 ;};
return GAA_OK;
@@ -816,7 +822,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_pgptrustdb.arg1, gaa_getstr, GAATMP_pgptrustdb.size1);
gaa_index++;
-#line 67 "cli.gaa"
+#line 70 "cli.gaa"
{ gaaval->pgp_trustdb = GAATMP_pgptrustdb.arg1 ;};
return GAA_OK;
@@ -826,7 +832,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_pgpkeyring.arg1, gaa_getstr, GAATMP_pgpkeyring.size1);
gaa_index++;
-#line 64 "cli.gaa"
+#line 67 "cli.gaa"
{ gaaval->pgp_keyring = GAATMP_pgpkeyring.arg1 ;};
return GAA_OK;
@@ -836,7 +842,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_pgpkeyfile.arg1, gaa_getstr, GAATMP_pgpkeyfile.size1);
gaa_index++;
-#line 61 "cli.gaa"
+#line 64 "cli.gaa"
{ gaaval->pgp_keyfile = GAATMP_pgpkeyfile.arg1 ;};
return GAA_OK;
@@ -846,7 +852,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_x509cafile.arg1, gaa_getstr, GAATMP_x509cafile.size1);
gaa_index++;
-#line 58 "cli.gaa"
+#line 61 "cli.gaa"
{ gaaval->x509_cafile = GAATMP_x509cafile.arg1 ;};
return GAA_OK;
@@ -854,7 +860,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
case GAAOPTID_ctypes:
OK = 0;
GAA_LIST_FILL(GAATMP_ctypes.arg1, gaa_getstr, char*, GAATMP_ctypes.size1);
-#line 55 "cli.gaa"
+#line 58 "cli.gaa"
{ gaaval->ctype = GAATMP_ctypes.arg1; gaaval->nctype = GAATMP_ctypes.size1 ;};
return GAA_OK;
@@ -862,7 +868,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
case GAAOPTID_kx:
OK = 0;
GAA_LIST_FILL(GAATMP_kx.arg1, gaa_getstr, char*, GAATMP_kx.size1);
-#line 51 "cli.gaa"
+#line 54 "cli.gaa"
{ gaaval->kx = GAATMP_kx.arg1; gaaval->nkx = GAATMP_kx.size1 ;};
return GAA_OK;
@@ -870,7 +876,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
case GAAOPTID_macs:
OK = 0;
GAA_LIST_FILL(GAATMP_macs.arg1, gaa_getstr, char*, GAATMP_macs.size1);
-#line 47 "cli.gaa"
+#line 50 "cli.gaa"
{ gaaval->macs = GAATMP_macs.arg1; gaaval->nmacs = GAATMP_macs.size1 ;};
return GAA_OK;
@@ -878,7 +884,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
case GAAOPTID_comp:
OK = 0;
GAA_LIST_FILL(GAATMP_comp.arg1, gaa_getstr, char*, GAATMP_comp.size1);
-#line 43 "cli.gaa"
+#line 46 "cli.gaa"
{ gaaval->comp = GAATMP_comp.arg1; gaaval->ncomp = GAATMP_comp.size1 ;};
return GAA_OK;
@@ -886,7 +892,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
case GAAOPTID_protocols:
OK = 0;
GAA_LIST_FILL(GAATMP_protocols.arg1, gaa_getstr, char*, GAATMP_protocols.size1);
-#line 39 "cli.gaa"
+#line 42 "cli.gaa"
{ gaaval->proto = GAATMP_protocols.arg1; gaaval->nproto = GAATMP_protocols.size1 ;};
return GAA_OK;
@@ -894,7 +900,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
case GAAOPTID_ciphers:
OK = 0;
GAA_LIST_FILL(GAATMP_ciphers.arg1, gaa_getstr, char*, GAATMP_ciphers.size1);
-#line 35 "cli.gaa"
+#line 38 "cli.gaa"
{ gaaval->ciphers = GAATMP_ciphers.arg1; gaaval->nciphers = GAATMP_ciphers.size1 ;};
return GAA_OK;
@@ -904,7 +910,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_recordsize.arg1, gaa_getint, GAATMP_recordsize.size1);
gaa_index++;
-#line 30 "cli.gaa"
+#line 33 "cli.gaa"
{ gaaval->record_size = GAATMP_recordsize.arg1 ;};
return GAA_OK;
@@ -914,32 +920,39 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_port.arg1, gaa_getint, GAATMP_port.size1);
gaa_index++;
-#line 27 "cli.gaa"
+#line 30 "cli.gaa"
{ gaaval->port = GAATMP_port.arg1 ;};
return GAA_OK;
break;
case GAAOPTID_fingerprint:
OK = 0;
-#line 24 "cli.gaa"
+#line 27 "cli.gaa"
{ gaaval->fingerprint = 1 ;};
return GAA_OK;
break;
case GAAOPTID_x509fmtder:
OK = 0;
-#line 21 "cli.gaa"
+#line 24 "cli.gaa"
{ gaaval->fmtder = 1 ;};
return GAA_OK;
break;
case GAAOPTID_crlf:
OK = 0;
-#line 18 "cli.gaa"
+#line 21 "cli.gaa"
{ gaaval->crlf = 1 ;};
return GAA_OK;
break;
+ case GAAOPTID_starttls:
+ OK = 0;
+#line 18 "cli.gaa"
+{ gaaval->starttls = 1 ;};
+
+ return GAA_OK;
+ break;
case GAAOPTID_resume:
OK = 0;
#line 15 "cli.gaa"
@@ -949,7 +962,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
break;
case GAA_REST:
GAA_LIST_FILL(GAAREST_tmp.arg1, gaa_getstr, char*, GAAREST_tmp.size1);
-#line 93 "cli.gaa"
+#line 96 "cli.gaa"
{ gaaval->rest_args = GAAREST_tmp.arg1; gaaval->nrest_args = GAAREST_tmp.size1 ;};
return GAA_OK;
@@ -978,14 +991,14 @@ int gaa(int argc, char **argv, gaainfo *gaaval)
if(inited == 0)
{
-#line 95 "cli.gaa"
+#line 98 "cli.gaa"
{ gaaval->resume=0; gaaval->port=443; gaaval->rest_args=NULL; gaaval->nrest_args=0; gaaval->ciphers=NULL;
gaaval->kx=NULL; gaaval->comp=NULL; gaaval->macs=NULL; gaaval->ctype=NULL; gaaval->nciphers=0;
gaaval->nkx=0; gaaval->ncomp=0; gaaval->nmacs=0; gaaval->nctype = 0; gaaval->record_size=0;
gaaval->fingerprint=0; gaaval->pgp_trustdb=NULL; gaaval->pgp_keyring=NULL;
gaaval->x509_cafile = NULL; gaaval->pgp_keyfile=NULL; gaaval->pgp_certfile=NULL;
gaaval->x509_keyfile=NULL; gaaval->x509_certfile=NULL; gaaval->crlf = 0;
- gaaval->srp_username=NULL; gaaval->srp_passwd=NULL; gaaval->fmtder = 0; ;};
+ gaaval->srp_username=NULL; gaaval->srp_passwd=NULL; gaaval->fmtder = 0; gaaval->starttls =0; ;};
}
inited = 1;
diff --git a/src/cli-gaa.h b/src/cli-gaa.h
index 16e8012e89..c773815efe 100644
--- a/src/cli-gaa.h
+++ b/src/cli-gaa.h
@@ -8,62 +8,64 @@ typedef struct _gaainfo gaainfo;
struct _gaainfo
{
-#line 92 "cli.gaa"
+#line 95 "cli.gaa"
char **rest_args;
-#line 91 "cli.gaa"
+#line 94 "cli.gaa"
int nrest_args;
-#line 81 "cli.gaa"
+#line 84 "cli.gaa"
char *srp_passwd;
-#line 78 "cli.gaa"
+#line 81 "cli.gaa"
char *srp_username;
-#line 75 "cli.gaa"
+#line 78 "cli.gaa"
char *x509_certfile;
-#line 72 "cli.gaa"
+#line 75 "cli.gaa"
char *x509_keyfile;
-#line 69 "cli.gaa"
+#line 72 "cli.gaa"
char *pgp_certfile;
-#line 66 "cli.gaa"
+#line 69 "cli.gaa"
char *pgp_trustdb;
-#line 63 "cli.gaa"
+#line 66 "cli.gaa"
char *pgp_keyring;
-#line 60 "cli.gaa"
+#line 63 "cli.gaa"
char *pgp_keyfile;
-#line 57 "cli.gaa"
+#line 60 "cli.gaa"
char *x509_cafile;
-#line 54 "cli.gaa"
+#line 57 "cli.gaa"
char **ctype;
-#line 53 "cli.gaa"
+#line 56 "cli.gaa"
int nctype;
-#line 50 "cli.gaa"
+#line 53 "cli.gaa"
char **kx;
-#line 49 "cli.gaa"
+#line 52 "cli.gaa"
int nkx;
-#line 46 "cli.gaa"
+#line 49 "cli.gaa"
char **macs;
-#line 45 "cli.gaa"
+#line 48 "cli.gaa"
int nmacs;
-#line 42 "cli.gaa"
+#line 45 "cli.gaa"
char **comp;
-#line 41 "cli.gaa"
+#line 44 "cli.gaa"
int ncomp;
-#line 38 "cli.gaa"
+#line 41 "cli.gaa"
char **proto;
-#line 37 "cli.gaa"
+#line 40 "cli.gaa"
int nproto;
-#line 34 "cli.gaa"
+#line 37 "cli.gaa"
char **ciphers;
-#line 33 "cli.gaa"
+#line 36 "cli.gaa"
int nciphers;
-#line 29 "cli.gaa"
+#line 32 "cli.gaa"
int record_size;
-#line 26 "cli.gaa"
+#line 29 "cli.gaa"
int port;
-#line 23 "cli.gaa"
+#line 26 "cli.gaa"
int fingerprint;
-#line 20 "cli.gaa"
+#line 23 "cli.gaa"
int fmtder;
-#line 17 "cli.gaa"
+#line 20 "cli.gaa"
int crlf;
+#line 17 "cli.gaa"
+ int starttls;
#line 14 "cli.gaa"
int resume;
diff --git a/src/cli.c b/src/cli.c
index 87938433d2..4bc63fd759 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -49,7 +49,7 @@
#define GERR(ret) fprintf(stderr, "* Error: %s\n", gnutls_strerror(ret))
/* global stuff here */
-int resume;
+int resume, starttls;
char *hostname = NULL;
int port;
int record_max_size;
@@ -69,15 +69,19 @@ char *x509_cafile;
char *x509_crlfile = NULL;
static int x509ctype;
+static gnutls_srp_client_credentials cred;
+static gnutls_anon_client_credentials anon_cred;
+static gnutls_certificate_credentials xcred;
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 */
+ /* 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_128, GNUTLS_CIPHER_RIJNDAEL_128_CBC,
+ GNUTLS_CIPHER_3DES_CBC,
GNUTLS_CIPHER_ARCFOUR_40, 0
};
int comp_priority[16] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 };
@@ -86,6 +90,21 @@ int cert_type_priority[16] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 };
/* end of global stuff */
+/* prototypes */
+typedef struct {
+ 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);
+
+
#define MAX(X,Y) (X >= Y ? X : Y);
#define DEFAULT_X509_CAFILE "x509/ca.pem"
#define DEFAULT_X509_KEYFILE2 "x509/clikey-dsa.pem"
@@ -101,6 +120,49 @@ int cert_type_priority[16] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 };
#define DEFAULT_SRP_USERNAME "test"
#define DEFAULT_SRP_PASSWD "test"
+/* initializes a gnutls_session with some defaults.
+ */
+static gnutls_session init_tls_session(void)
+{
+ gnutls_session session;
+
+ gnutls_init(&session, GNUTLS_CLIENT);
+
+ /* allow the use of private ciphersuites.
+ */
+ gnutls_handshake_set_private_extensions(session, 1);
+
+ 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_cred_set(session, GNUTLS_CRD_ANON, anon_cred);
+ if (srp_username != NULL)
+ gnutls_cred_set(session, GNUTLS_CRD_SRP, cred);
+ gnutls_cred_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
+
+ /* 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) {
+ 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;
+}
+
static void gaa_parser(int argc, char **argv);
@@ -109,22 +171,17 @@ int main(int argc, char **argv)
int err, ret;
int sd, ii, i;
struct sockaddr_in sa;
- gnutls_session session;
char buffer[MAX_BUF + 1];
char *session_data = NULL;
char *session_id = NULL;
int session_data_size, alert;
int session_id_size;
- char *tmp_session_id;
- int tmp_session_id_size;
fd_set rset;
int maxfd;
struct timeval tv;
int user_term = 0;
- gnutls_srp_client_credentials cred;
- gnutls_anon_client_credentials anon_cred;
- gnutls_certificate_credentials xcred;
struct hostent *server_host;
+ socket_st hd;
gaa_parser(argc, argv);
@@ -148,31 +205,35 @@ int main(int argc, char **argv)
if (x509_cafile != NULL) {
ret =
- gnutls_certificate_set_x509_trust_file(xcred, x509_cafile,
- x509ctype);
+ 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);
+ printf("Processed %d CA certificate(s).\n", ret);
}
}
if (x509_certfile != NULL) {
ret =
- gnutls_certificate_set_x509_key_file(xcred, x509_certfile,
- x509_keyfile, x509ctype);
+ 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",
+ 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,
+ 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",
+ fprintf(stderr,
+ "Error setting the x509 key files ('%s', '%s')\n",
pgp_certfile, pgp_keyfile);
}
}
@@ -194,13 +255,13 @@ int main(int argc, char **argv)
/* gnutls_certificate_client_callback_func( xcred, cert_callback); */
/* SRP stuff */
- if (srp_username!=NULL) {
+ if (srp_username != NULL) {
if (gnutls_srp_allocate_client_cred(&cred) < 0) {
- fprintf(stderr, "SRP authentication error\n");
+ fprintf(stderr, "SRP authentication error\n");
}
gnutls_srp_set_client_cred(cred, srp_username, srp_passwd);
}
-
+
/* ANON stuff */
if (gnutls_anon_allocate_client_cred(&anon_cred) < 0) {
fprintf(stderr, "Anonymous authentication error\n");
@@ -229,110 +290,63 @@ int main(int argc, char **argv)
err = connect(sd, (SA *) & sa, sizeof(sa));
ERR(err, "connect");
+ hd.secure = 0;
+ hd.fd = sd;
+
+ hd.session = init_tls_session();
+ if (starttls)
+ goto after_handshake;
+
for (i = 0; i < 2; i++) {
- gnutls_init(&session, GNUTLS_CLIENT);
- /* allow the use of private ciphersuites.
- */
- gnutls_handshake_set_private_extensions( session, 1);
if (i == 1) {
- gnutls_session_set_data(session, session_data, session_data_size);
+ hd.session = init_tls_session();
+ gnutls_session_set_data(hd.session, session_data,
+ session_data_size);
free(session_data);
}
- 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_cred_set(session, GNUTLS_CRD_ANON, anon_cred);
- if (srp_username!=NULL)
- gnutls_cred_set(session, GNUTLS_CRD_SRP, cred);
- gnutls_cred_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
-
- /* 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) {
- 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);
- }
- }
-
/* This TLS extension may break old implementations.
*/
- gnutls_transport_set_ptr(session, sd);
- do {
- ret = gnutls_handshake(session);
- } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
+
+ ret = do_handshake(&hd);
if (ret < 0) {
if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED
|| ret == GNUTLS_E_FATAL_ALERT_RECEIVED) {
- alert = gnutls_alert_get(session);
+ alert = gnutls_alert_get(hd.session);
printf("*** Received alert [%d]: %s\n",
alert, gnutls_alert_get_name(alert));
}
fprintf(stderr, "*** Handshake has failed\n");
gnutls_perror(ret);
- gnutls_deinit(session);
+ gnutls_deinit(hd.session);
return 1;
} else {
printf("- Handshake was completed\n");
- if (gnutls_session_is_resumed( session)!=0)
- printf("*** This is a resumed session\n");
- }
-
- if (i == 1) { /* resume */
- /* check if we actually resumed the previous session */
-
- gnutls_session_get_id(session, NULL, &tmp_session_id_size);
- tmp_session_id = malloc(tmp_session_id_size);
- gnutls_session_get_id(session, tmp_session_id,
- &tmp_session_id_size);
-
- if (memcmp(tmp_session_id, session_id, session_id_size) == 0) {
- printf("- Previous session was resumed\n");
- } else {
- fprintf(stderr, "*** Previous session was NOT resumed\n");
- }
- free(tmp_session_id);
- free(session_id);
+ if (gnutls_session_is_resumed(hd.session) != 0)
+ printf("*** This is a resumed session\n");
}
if (resume != 0 && i == 0) {
- gnutls_session_get_data(session, NULL, &session_data_size);
+ gnutls_session_get_data(hd.session, NULL, &session_data_size);
session_data = malloc(session_data_size);
- gnutls_session_get_data(session, session_data, &session_data_size);
+ gnutls_session_get_data(hd.session, session_data,
+ &session_data_size);
- gnutls_session_get_id(session, NULL, &session_id_size);
+ gnutls_session_get_id(hd.session, NULL, &session_id_size);
session_id = malloc(session_id_size);
- gnutls_session_get_id(session, session_id, &session_id_size);
+ gnutls_session_get_id(hd.session, session_id, &session_id_size);
/* print some information */
- print_info(session);
+ print_info(hd.session);
printf("- Disconnecting\n");
- do {
- ret = gnutls_bye(session, GNUTLS_SHUT_RDWR);
- } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
-
- shutdown(sd, SHUT_WR);
- close(sd);
-
- gnutls_deinit(session);
+ socket_bye(hd);
printf
("\n\n- Connecting again- trying to resume previous session\n");
@@ -347,7 +361,9 @@ int main(int argc, char **argv)
}
/* print some information */
- print_info(session);
+ print_info(hd.session);
+
+ after_handshake:
printf("\n- Simple Client Mode:\n\n");
@@ -363,92 +379,68 @@ int main(int argc, char **argv)
if (FD_ISSET(sd, &rset)) {
bzero(buffer, MAX_BUF + 1);
- do {
- ret = gnutls_record_recv(session, buffer, MAX_BUF);
- } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
- /* remove new line */
-
- if (gnutls_error_is_fatal(ret) == 1 || ret == 0) {
- if (ret == 0) {
- printf("- Peer has closed the GNUTLS connection\n");
- break;
- } else {
- fprintf(stderr,
- "*** Received corrupted data(%d) - server has terminated the connection abnormally\n",
- ret);
- break;
- }
- } else {
- if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED
- || ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
- printf("* Received alert [%d]\n", gnutls_alert_get(session));
- if (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(session);
- } while (ret == GNUTLS_E_AGAIN
- || ret == GNUTLS_E_INTERRUPTED);
-
- if (ret == 0) {
- printf("* Rehandshake was performed\n");
- } else {
- printf("* Rehandshake Failed [%d]\n", ret);
- }
- }
- if (ret > 0) {
- if (quiet!=0) printf("- Received[%d]: ", ret);
- for (ii = 0; ii < ret; ii++) {
- fputc(buffer[ii], stdout);
- }
- fputs("\n", stdout);
+ ret = socket_recv(hd, buffer, MAX_BUF);
+
+ if (ret == 0) {
+ printf("- Peer has closed the GNUTLS connection\n");
+ break;
+ } else if (ret < 0) {
+ fprintf(stderr,
+ "*** Received corrupted data(%d) - server has terminated the connection abnormally\n",
+ ret);
+ break;
+ } else if (ret > 0) {
+ if (quiet != 0)
+ printf("- Received[%d]: ", ret);
+ for (ii = 0; ii < ret; ii++) {
+ fputc(buffer[ii], stdout);
}
}
+
if (user_term != 0)
break;
}
if (FD_ISSET(fileno(stdin), &rset)) {
if (fgets(buffer, MAX_BUF, stdin) == NULL) {
- do {
- ret = gnutls_bye(session, GNUTLS_SHUT_WR);
- } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
- user_term = 1;
- continue;
- }
- do {
- if ( crlf != 0) {
- char* b=strchr( buffer, '\n');
- if (b!=NULL)
- strcpy( b, "\r\n");
+ if (hd.secure == 0) {
+ fprintf(stderr, "*** Starting TLS handshake\n");
+ ret = do_handshake(&hd);
+ if (ret < 0) {
+ fprintf(stderr, "*** Handshake has failed\n");
+ gnutls_perror(ret);
+ gnutls_deinit(hd.session);
+ }
+ continue;
+ } else {
+ socket_bye(hd);
+ user_term = 1;
+ continue;
}
-
- ret = gnutls_record_send(session, buffer, strlen(buffer));
- } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
+ }
+
+ 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);
+ if (quiet != 0)
+ printf("- Sent: %d bytes\n", ret);
} else
GERR(ret);
}
}
- if (user_term != 0)
- do
- ret = gnutls_bye(session, GNUTLS_SHUT_RDWR);
- while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
- shutdown(sd, SHUT_RDWR); /* no more receptions */
- close(sd);
+ if (user_term != 0)
+ socket_bye(hd);
- gnutls_deinit(session);
- if (srp_username!=NULL)
+ if (srp_username != NULL)
gnutls_srp_free_client_cred(cred);
gnutls_certificate_free_cred(xcred);
gnutls_anon_free_client_cred(anon_cred);
@@ -471,6 +463,7 @@ void gaa_parser(int argc, char **argv)
exit(1);
}
+ starttls = info.starttls;
resume = info.resume;
port = info.port;
record_max_size = info.record_size;
@@ -517,19 +510,19 @@ void gaa_parser(int argc, char **argv)
else
srp_username = DEFAULT_SRP_USERNAME;
#else
- srp_username = info.srp_username;
- srp_passwd = info.srp_passwd;
- x509_cafile = info.x509_cafile;
- x509_keyfile = info.x509_keyfile;
- x509_certfile = info.x509_certfile;
- pgp_keyfile = info.pgp_keyfile;
- pgp_certfile = info.pgp_certfile;
+ srp_username = info.srp_username;
+ srp_passwd = info.srp_passwd;
+ x509_cafile = info.x509_cafile;
+ x509_keyfile = info.x509_keyfile;
+ x509_certfile = info.x509_certfile;
+ pgp_keyfile = info.pgp_keyfile;
+ pgp_certfile = info.pgp_certfile;
#endif
pgp_keyring = info.pgp_keyring;
pgp_trustdb = info.pgp_trustdb;
-
+
crlf = info.crlf;
if (info.nrest_args == 0)
@@ -617,7 +610,106 @@ void gaa_parser(int argc, char **argv)
}
-void cli_version(void) {
- fprintf(stderr, "GNU TLS test client, ");
- fprintf(stderr, "version %s.\n", LIBGNUTLS_VERSION);
+void cli_version(void)
+{
+ fprintf(stderr, "GNU TLS test client, ");
+ fprintf(stderr, "version %s.\n", LIBGNUTLS_VERSION);
+}
+
+
+
+/* Functions to manipulate sockets
+ */
+
+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;
+}
+
+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, strlen(buffer));
+ } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
+ else
+ do {
+ ret = send(socket.fd, buffer, strlen(buffer), 0);
+ } while (ret == -1 && errno == EINTR);
+
+
+ return ret;
+}
+
+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);
+ }
+
+ shutdown(socket.fd, SHUT_RDWR); /* no more receptions */
+ close(socket.fd);
+}
+
+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 {
+ printf("* Rehandshake Failed [%d]\n", ret);
+ }
+ }
+}
+
+void check_alert(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);
+ }
+}
+
+int do_handshake(socket_st* socket)
+{
+ int ret;
+ gnutls_transport_set_ptr(socket->session, socket->fd);
+ do {
+ ret = gnutls_handshake(socket->session);
+ } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
+
+ socket->secure = 1;
+ return ret;
}
diff --git a/src/cli.gaa b/src/cli.gaa
index deb557479b..0916057fb0 100644
--- a/src/cli.gaa
+++ b/src/cli.gaa
@@ -14,6 +14,9 @@ helpnode "GNU TLS test client\nUsage: gnutls-cli [options] hostname\n\n"
#int resume;
option (r, resume) { $resume = 1 } "Connect, establish a session. Connect again and resume this session."
+#int starttls;
+option (s, starttls) { $starttls = 1 } "Connect, establish a plain session and start TLS when EOF is sent."
+
#int crlf;
option (crlf) { $crlf = 1 } "Send CR LF instead of LF."
@@ -98,6 +101,6 @@ init { $resume=0; $port=443; $rest_args=NULL; $nrest_args=0; $ciphers=NULL;
$fingerprint=0; $pgp_trustdb=NULL; $pgp_keyring=NULL;
$x509_cafile = NULL; $pgp_keyfile=NULL; $pgp_certfile=NULL;
$x509_keyfile=NULL; $x509_certfile=NULL; $crlf = 0;
- $srp_username=NULL; $srp_passwd=NULL; $fmtder = 0; }
+ $srp_username=NULL; $srp_passwd=NULL; $fmtder = 0; $starttls =0; }