summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2005-11-07 22:24:48 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2005-11-07 22:24:48 +0000
commitad4ed44c65e753e6d3a00104c049dd81826ccbf3 (patch)
treec7511d77a37287b567c2f31f3e5dfa9af956d635 /src
parent31168918162ee35315f025a9d8aeec67a81c7a7c (diff)
downloadgnutls-ad4ed44c65e753e6d3a00104c049dd81826ccbf3.tar.gz
This is the initial commit in the 1.3 branch. Ported from the PSK branch:
* PSK ciphersuites have been added. * The session resumption data are now system independent.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am9
-rw-r--r--src/cli-gaa.c124
-rw-r--r--src/cli-gaa.h8
-rw-r--r--src/cli.c32
-rw-r--r--src/cli.gaa8
-rw-r--r--src/common.c13
-rw-r--r--src/crypt.c7
-rwxr-xr-xsrc/gnutls-http-serv2
-rw-r--r--src/psk-gaa.c803
-rw-r--r--src/psk-gaa.h37
-rw-r--r--src/psk.c260
-rw-r--r--src/psk.gaa29
-rw-r--r--src/serv.c45
-rw-r--r--src/serv.gaa5
14 files changed, 1324 insertions, 58 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 7c8c0ef83f..1aa64cb87d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -24,7 +24,7 @@ SUBDIRS = srp x509 openpgp cfg
INCLUDES = -I$(top_srcdir)/lib -I../includes -I$(top_srcdir)/includes \
-I$(top_srcdir)/gl -I$(srcdir)/cfg
-bin_PROGRAMS = gnutls-serv gnutls-cli srptool gnutls-cli-debug certtool
+bin_PROGRAMS = gnutls-serv gnutls-cli psktool srptool gnutls-cli-debug certtool
gnutls_serv_SOURCES = serv.gaa serv-gaa.h serv-gaa.c list.h serv.c \
common.h common.c
@@ -36,6 +36,11 @@ srptool_LDADD = ../lib/libgnutls.la ../libextra/libgnutls-extra.la \
$(LIBGCRYPT_LIBS) $(LIBTASN1_LIBS) $(LIBOPENCDK_LIBS) \
../gl/libgnu.la
+psktool_SOURCES = psk.gaa psk-gaa.h psk-gaa.c psk.c
+psktool_LDADD = ../lib/libgnutls.la ../libextra/libgnutls-extra.la \
+ $(LIBGCRYPT_LIBS) $(LIBTASN1_LIBS) $(LIBOPENCDK_LIBS) \
+ ../gl/libgnu.la
+
gnutls_cli_SOURCES = cli.gaa cli-gaa.h cli-gaa.c cli.c common.h \
common.c
gnutls_cli_LDADD = ../lib/libgnutls.la ../libextra/libgnutls-extra.la \
@@ -66,6 +71,8 @@ errcodes_LDADD = ../lib/libgnutls.la $(LIBGCRYPT_LIBS) $(LIBTASN1_LIBS)
+psk-gaa.c: psk.gaa
+ -gaa psk.gaa -o psk-gaa.c -i psk-gaa.h
crypt-gaa.c: crypt.gaa
-gaa crypt.gaa -o crypt-gaa.c -i crypt-gaa.h
certtool-gaa.c: certtool.gaa
diff --git a/src/cli-gaa.c b/src/cli-gaa.c
index 7597db3255..d18c8633b6 100644
--- a/src/cli-gaa.c
+++ b/src/cli-gaa.c
@@ -155,6 +155,8 @@ void gaa_help(void)
__gaa_helpsingle(0, "x509certfile", "FILE ", "X.509 Certificate file to use.");
__gaa_helpsingle(0, "srpusername", "NAME ", "SRP username to use.");
__gaa_helpsingle(0, "srppasswd", "PASSWD ", "SRP password to use.");
+ __gaa_helpsingle(0, "pskusername", "NAME ", "PSK username to use.");
+ __gaa_helpsingle(0, "pskkey", "KEY ", "PSK key (in hex) to use.");
__gaa_helpsingle(0, "insecure", "", "Don't abort program if server certificate can't be validated.");
__gaa_helpsingle('l', "list", "", "Print a list of the supported algorithms and modes.");
__gaa_helpsingle('h', "help", "", "prints this help");
@@ -174,10 +176,14 @@ typedef struct _gaainfo gaainfo;
struct _gaainfo
{
-#line 113 "cli.gaa"
+#line 119 "cli.gaa"
char *rest_args;
-#line 104 "cli.gaa"
+#line 110 "cli.gaa"
int insecure;
+#line 107 "cli.gaa"
+ char *psk_key;
+#line 104 "cli.gaa"
+ char *psk_username;
#line 101 "cli.gaa"
char *srp_passwd;
#line 98 "cli.gaa"
@@ -300,40 +306,42 @@ static int gaa_error = 0;
#define GAA_MULTIPLE_OPTION 3
#define GAA_REST 0
-#define GAA_NB_OPTION 33
+#define GAA_NB_OPTION 35
#define GAAOPTID_copyright 1
#define GAAOPTID_version 2
#define GAAOPTID_help 3
#define GAAOPTID_list 4
#define GAAOPTID_insecure 5
-#define GAAOPTID_srppasswd 6
-#define GAAOPTID_srpusername 7
-#define GAAOPTID_x509certfile 8
-#define GAAOPTID_x509keyfile 9
-#define GAAOPTID_pgpcertfile 10
-#define GAAOPTID_pgptrustdb 11
-#define GAAOPTID_pgpkeyring 12
-#define GAAOPTID_pgpkeyfile 13
-#define GAAOPTID_x509crlfile 14
-#define GAAOPTID_x509cafile 15
-#define GAAOPTID_ctypes 16
-#define GAAOPTID_kx 17
-#define GAAOPTID_macs 18
-#define GAAOPTID_comp 19
-#define GAAOPTID_protocols 20
-#define GAAOPTID_ciphers 21
-#define GAAOPTID_verbose 22
-#define GAAOPTID_recordsize 23
-#define GAAOPTID_port 24
-#define GAAOPTID_print_cert 25
-#define GAAOPTID_xml 26
-#define GAAOPTID_disable_extensions 27
-#define GAAOPTID_fingerprint 28
-#define GAAOPTID_x509fmtder 29
-#define GAAOPTID_crlf 30
-#define GAAOPTID_starttls 31
-#define GAAOPTID_resume 32
-#define GAAOPTID_debug 33
+#define GAAOPTID_pskkey 6
+#define GAAOPTID_pskusername 7
+#define GAAOPTID_srppasswd 8
+#define GAAOPTID_srpusername 9
+#define GAAOPTID_x509certfile 10
+#define GAAOPTID_x509keyfile 11
+#define GAAOPTID_pgpcertfile 12
+#define GAAOPTID_pgptrustdb 13
+#define GAAOPTID_pgpkeyring 14
+#define GAAOPTID_pgpkeyfile 15
+#define GAAOPTID_x509crlfile 16
+#define GAAOPTID_x509cafile 17
+#define GAAOPTID_ctypes 18
+#define GAAOPTID_kx 19
+#define GAAOPTID_macs 20
+#define GAAOPTID_comp 21
+#define GAAOPTID_protocols 22
+#define GAAOPTID_ciphers 23
+#define GAAOPTID_verbose 24
+#define GAAOPTID_recordsize 25
+#define GAAOPTID_port 26
+#define GAAOPTID_print_cert 27
+#define GAAOPTID_xml 28
+#define GAAOPTID_disable_extensions 29
+#define GAAOPTID_fingerprint 30
+#define GAAOPTID_x509fmtder 31
+#define GAAOPTID_crlf 32
+#define GAAOPTID_starttls 33
+#define GAAOPTID_resume 34
+#define GAAOPTID_debug 35
#line 168 "gaa.skel"
@@ -520,6 +528,18 @@ static float gaa_getfloat(char *arg)
}
/* option structures */
+struct GAAOPTION_pskkey
+{
+ char* arg1;
+ int size1;
+};
+
+struct GAAOPTION_pskusername
+{
+ char* arg1;
+ int size1;
+};
+
struct GAAOPTION_srppasswd
{
char* arg1;
@@ -670,6 +690,8 @@ static int gaa_get_option_num(char *str, int status)
switch(status)
{
case GAA_LETTER_OPTION:
+ GAA_CHECK1STR("", GAAOPTID_pskkey);
+ GAA_CHECK1STR("", GAAOPTID_pskusername);
GAA_CHECK1STR("", GAAOPTID_srppasswd);
GAA_CHECK1STR("", GAAOPTID_srpusername);
GAA_CHECK1STR("", GAAOPTID_x509certfile);
@@ -714,6 +736,8 @@ static int gaa_get_option_num(char *str, int status)
GAA_CHECKSTR("help", GAAOPTID_help);
GAA_CHECKSTR("list", GAAOPTID_list);
GAA_CHECKSTR("insecure", GAAOPTID_insecure);
+ GAA_CHECKSTR("pskkey", GAAOPTID_pskkey);
+ GAA_CHECKSTR("pskusername", GAAOPTID_pskusername);
GAA_CHECKSTR("srppasswd", GAAOPTID_srppasswd);
GAA_CHECKSTR("srpusername", GAAOPTID_srpusername);
GAA_CHECKSTR("x509certfile", GAAOPTID_x509certfile);
@@ -754,6 +778,8 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
{
int OK = 0;
int gaa_last_non_option;
+ struct GAAOPTION_pskkey GAATMP_pskkey;
+ struct GAAOPTION_pskusername GAATMP_pskusername;
struct GAAOPTION_srppasswd GAATMP_srppasswd;
struct GAAOPTION_srpusername GAATMP_srpusername;
struct GAAOPTION_x509certfile GAATMP_x509certfile;
@@ -795,39 +821,59 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
{
case GAAOPTID_copyright:
OK = 0;
-#line 111 "cli.gaa"
+#line 117 "cli.gaa"
{ print_license(); exit(0); ;};
return GAA_OK;
break;
case GAAOPTID_version:
OK = 0;
-#line 110 "cli.gaa"
+#line 116 "cli.gaa"
{ cli_version(); exit(0); ;};
return GAA_OK;
break;
case GAAOPTID_help:
OK = 0;
-#line 108 "cli.gaa"
+#line 114 "cli.gaa"
{ gaa_help(); exit(0); ;};
return GAA_OK;
break;
case GAAOPTID_list:
OK = 0;
-#line 107 "cli.gaa"
+#line 113 "cli.gaa"
{ print_list(); exit(0); ;};
return GAA_OK;
break;
case GAAOPTID_insecure:
OK = 0;
-#line 105 "cli.gaa"
+#line 111 "cli.gaa"
{ gaaval->insecure = 1 ;};
return GAA_OK;
break;
+ case GAAOPTID_pskkey:
+ OK = 0;
+ GAA_TESTMOREARGS;
+ GAA_FILL(GAATMP_pskkey.arg1, gaa_getstr, GAATMP_pskkey.size1);
+ gaa_index++;
+#line 108 "cli.gaa"
+{ gaaval->psk_key = GAATMP_pskkey.arg1 ;};
+
+ return GAA_OK;
+ break;
+ case GAAOPTID_pskusername:
+ OK = 0;
+ GAA_TESTMOREARGS;
+ GAA_FILL(GAATMP_pskusername.arg1, gaa_getstr, GAATMP_pskusername.size1);
+ gaa_index++;
+#line 105 "cli.gaa"
+{ gaaval->psk_username = GAATMP_pskusername.arg1 ;};
+
+ return GAA_OK;
+ break;
case GAAOPTID_srppasswd:
OK = 0;
GAA_TESTMOREARGS;
@@ -1073,7 +1119,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAAREST_tmp.arg1, gaa_getstr, GAAREST_tmp.size1);
gaa_index++;
-#line 114 "cli.gaa"
+#line 120 "cli.gaa"
{ gaaval->rest_args = GAAREST_tmp.arg1; ;};
return GAA_OK;
@@ -1102,7 +1148,7 @@ int gaa(int argc, char **argv, gaainfo *gaaval)
if(inited == 0)
{
-#line 116 "cli.gaa"
+#line 122 "cli.gaa"
{ gaaval->resume=0; gaaval->port=443; gaaval->rest_args=NULL; 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;
@@ -1110,7 +1156,7 @@ int gaa(int argc, char **argv, gaainfo *gaaval)
gaaval->x509_cafile = NULL; gaaval->pgp_keyfile=NULL; gaaval->pgp_certfile=NULL; gaaval->disable_extensions = 0;
gaaval->x509_keyfile=NULL; gaaval->x509_certfile=NULL; gaaval->crlf = 0; gaaval->xml = 0;
gaaval->srp_username=NULL; gaaval->srp_passwd=NULL; gaaval->fmtder = 0; gaaval->starttls =0;
- gaaval->debug = 0; gaaval->print_cert = 0; gaaval->verbose = 0; ;};
+ gaaval->debug = 0; gaaval->print_cert = 0; gaaval->verbose = 0; gaaval->psk_key = 0; gaaval->psk_username = NULL; ;};
}
inited = 1;
diff --git a/src/cli-gaa.h b/src/cli-gaa.h
index ecf73528a9..c51b08dde2 100644
--- a/src/cli-gaa.h
+++ b/src/cli-gaa.h
@@ -8,10 +8,14 @@ typedef struct _gaainfo gaainfo;
struct _gaainfo
{
-#line 113 "cli.gaa"
+#line 119 "cli.gaa"
char *rest_args;
-#line 104 "cli.gaa"
+#line 110 "cli.gaa"
int insecure;
+#line 107 "cli.gaa"
+ char *psk_key;
+#line 104 "cli.gaa"
+ char *psk_username;
#line 101 "cli.gaa"
char *srp_passwd;
#line 98 "cli.gaa"
diff --git a/src/cli.c b/src/cli.c
index eeef260831..d256c59dae 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -76,16 +76,19 @@ static int x509ctype;
static int disable_extensions;
static int debug;
+char* psk_username;
+gnutls_datum psk_key;
-static gnutls_srp_client_credentials srp_cred;
-static gnutls_anon_client_credentials anon_cred;
-static gnutls_certificate_credentials xcred;
+static gnutls_srp_client_credentials_t srp_cred;
+static gnutls_psk_client_credentials_t psk_cred;
+static gnutls_anon_client_credentials_t anon_cred;
+static gnutls_certificate_credentials_t xcred;
int protocol_priority[PRI_MAX] =
{ GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
int kx_priority[PRI_MAX] =
{ GNUTLS_KX_DHE_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA,
- GNUTLS_KX_SRP_RSA, GNUTLS_KX_SRP_DSS, GNUTLS_KX_SRP,
+ GNUTLS_KX_SRP_RSA, GNUTLS_KX_SRP_DSS, GNUTLS_KX_SRP, GNUTLS_KX_PSK,
/* Do not use anonymous authentication, unless you know what that means */
GNUTLS_KX_RSA_EXPORT, GNUTLS_KX_ANON_DH, 0
};
@@ -368,6 +371,7 @@ static gnutls_session init_tls_session(const char *hostname)
gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred);
gnutls_credentials_set(session, GNUTLS_CRD_SRP, srp_cred);
+ gnutls_credentials_set(session, GNUTLS_CRD_PSK, psk_cred);
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
gnutls_certificate_client_set_retrieve_function(xcred, cert_callback);
@@ -674,6 +678,9 @@ int main(int argc, char **argv)
#ifdef ENABLE_SRP
gnutls_srp_free_client_credentials(srp_cred);
#endif
+#ifdef ENABLE_PSK
+ gnutls_psk_free_client_credentials(psk_cred);
+#endif
gnutls_certificate_free_credentials(xcred);
@@ -721,6 +728,13 @@ void gaa_parser(int argc, char **argv)
pgp_keyfile = info.pgp_keyfile;
pgp_certfile = info.pgp_certfile;
+ psk_username = info.psk_username;
+ psk_key.data = (unsigned char*)info.psk_key;
+ if (info.psk_key != NULL)
+ psk_key.size = strlen(info.psk_key);
+ else
+ psk_key.size = 0;
+
pgp_keyring = info.pgp_keyring;
pgp_trustdb = info.pgp_trustdb;
@@ -990,6 +1004,16 @@ static void init_global_tls_stuff(void)
srp_username_callback);
#endif
+#ifdef ENABLE_PSK
+ /* SRP stuff */
+ if (gnutls_psk_allocate_client_credentials(&psk_cred) < 0) {
+ fprintf(stderr, "PSK authentication error\n");
+ }
+
+ gnutls_psk_set_client_credentials(psk_cred,
+ psk_username, &psk_key, GNUTLS_PSK_KEY_HEX);
+#endif
+
#ifdef ENABLE_ANON
/* ANON stuff */
diff --git a/src/cli.gaa b/src/cli.gaa
index b163222cf2..8a6a9f03d8 100644
--- a/src/cli.gaa
+++ b/src/cli.gaa
@@ -101,6 +101,12 @@ option (srpusername) STR "NAME" { $srp_username = $1 } "SRP username to use."
#char *srp_passwd;
option (srppasswd) STR "PASSWD" { $srp_passwd = $1 } "SRP password to use."
+#char *psk_username;
+option (pskusername) STR "NAME" { $psk_username = $1 } "PSK username to use."
+
+#char *psk_key;
+option (pskkey) STR "KEY" { $psk_key = $1 } "PSK key (in hex) to use."
+
#int insecure;
option (insecure) { $insecure = 1 } "Don't abort program if server certificate can't be validated."
@@ -120,6 +126,6 @@ init { $resume=0; $port=443; $rest_args=NULL; $ciphers=NULL;
$x509_cafile = NULL; $pgp_keyfile=NULL; $pgp_certfile=NULL; $disable_extensions = 0;
$x509_keyfile=NULL; $x509_certfile=NULL; $crlf = 0; $xml = 0;
$srp_username=NULL; $srp_passwd=NULL; $fmtder = 0; $starttls =0;
- $debug = 0; $print_cert = 0; $verbose = 0; }
+ $debug = 0; $print_cert = 0; $verbose = 0; $psk_key = 0; $psk_username = NULL; }
diff --git a/src/common.c b/src/common.c
index d6db9f8ea1..01cee3804c 100644
--- a/src/common.c
+++ b/src/common.c
@@ -476,6 +476,16 @@ int print_info(gnutls_session session, const char *hostname)
gnutls_srp_server_get_username(session));
break;
#endif
+#ifdef ENABLE_PSK
+ case GNUTLS_CRD_PSK:
+ /* This should be only called in server
+ * side.
+ */
+ if (gnutls_psk_server_get_username(session) != NULL)
+ printf("- PSK authentication. Connected as '%s'\n",
+ gnutls_psk_server_get_username(session));
+ break;
+#endif
case GNUTLS_CRD_CERTIFICATE:
{
char dns[256];
@@ -567,6 +577,7 @@ void print_list(void)
printf(", RSA-EXPORT");
printf(", DHE-DSS");
printf(", DHE-RSA");
+ printf(", PSK");
printf(", SRP");
printf(", SRP-RSA");
printf(", SRP-DSS");
@@ -688,6 +699,8 @@ void parse_kx(char **kx, int nkx, int *kx_priority)
kx_priority[j++] = GNUTLS_KX_SRP_DSS;
else if (strcasecmp(kx[i], "RSA") == 0)
kx_priority[j++] = GNUTLS_KX_RSA;
+ else if (strcasecmp(kx[i], "PSK") == 0)
+ kx_priority[j++] = GNUTLS_KX_PSK;
else if (strcasecmp(kx[i], "RSA-EXPORT") == 0)
kx_priority[j++] = GNUTLS_KX_RSA_EXPORT;
else if (strncasecmp(kx[i], "DHE-RSA", 7) == 0)
diff --git a/src/crypt.c b/src/crypt.c
index 8dbf967c65..e5362d6b33 100644
--- a/src/crypt.c
+++ b/src/crypt.c
@@ -387,10 +387,9 @@ int main(int argc, char **argv)
exit(1);
}
- if ((ret = gnutls_global_init_extra()) < 0) {
- fprintf(stderr, "global_init_extra: %s\n", gnutls_strerror(ret));
- exit(1);
- }
+#ifdef HAVE_UMASK
+ umask(066);
+#endif
if (gaa(argc, argv, &info) != -1) {
fprintf(stderr, "Error in the arguments.\n");
diff --git a/src/gnutls-http-serv b/src/gnutls-http-serv
index 278cd177a0..7df9387529 100755
--- a/src/gnutls-http-serv
+++ b/src/gnutls-http-serv
@@ -3,5 +3,5 @@
./gnutls-serv --http --x509certfile x509/cert.pem --x509keyfile x509/key.pem --x509cafile x509/ca.pem \
--x509dsacertfile x509/cert-dsa.pem --x509dsakeyfile x509/key-dsa.pem \
--srppasswd srp/tpasswd --srppasswdconf srp/tpasswd.conf \
- --pgpkeyfile openpgp/sec.asc --pgpcertfile openpgp/pub.asc $*
+ --pgpkeyfile openpgp/sec.asc --pgpcertfile openpgp/pub.asc --pskpasswd psk/passwd.psk $*
diff --git a/src/psk-gaa.c b/src/psk-gaa.c
new file mode 100644
index 0000000000..0c8b7b90de
--- /dev/null
+++ b/src/psk-gaa.c
@@ -0,0 +1,803 @@
+/* File generated by GAA 1.6.6
+ */
+#define GAA_NO_WIN32
+#line 1 "psk.gaa"
+
+
+/* C declarations */
+
+#include <config.h>
+#ifdef _WIN32
+# include <io.h>
+#endif
+
+void psktool_version(void);
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifndef GAA_NO_WIN32
+#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(WINDOWS)
+#define GAA_WIN32
+#endif
+#endif
+
+static void* gaa_malloc( size_t size) {
+void* ret;
+ ret = malloc(size);
+ if (ret==NULL) {
+ fprintf(stderr, "gaa: could not allocate memory");
+ exit(1);
+ }
+ return ret;
+}
+
+static void __gaa_helpsingle(char short_name, char *name,
+ char *arg_desc, char *opt_help)
+{
+ int col1, col3, col4, tabsize = 3, curr;
+ int i;
+
+ col1 = 5; /* Default values */
+ col3 = 30;
+ col4 = 70;
+
+ curr = 0;
+ for(i = 0; i < col1; i++)
+ {
+ printf(" ");
+ curr++;
+ }
+ if(short_name)
+ {
+ if(name && *name)
+ {
+ printf("-%c, ", short_name);
+ curr += 4;
+ }
+ else
+ {
+ printf("-%c ", short_name);
+ curr += 3;
+ }
+ }
+ if(name && *name)
+ {
+ printf("--%s ", name);
+ curr += 3 + strlen(name);
+ }
+ if(arg_desc && *arg_desc)
+ {
+ printf("%s ", arg_desc);
+ curr += 1 + strlen(arg_desc);
+ }
+ if(curr >= col3)
+ {
+ printf("\n");
+ curr = 0;
+ }
+ if(opt_help) /* let's print the option's help body */
+ {
+ const char *str = opt_help;
+ while(*str)
+ {
+ while(curr < col3)
+ {
+ printf(" ");
+ curr++;
+ }
+ switch(*str)
+ {
+ case '\n':
+ printf("\n");
+ curr = 0;
+ break;
+ case '\t':
+ do
+ {
+ printf(" ");
+ curr++;
+ }
+ while((curr - col3) % tabsize != 0 && curr < col4);
+ case ' ':
+ if(*str == ' ')
+ {
+ curr++;
+ printf(" ");
+ }
+ for(i = 1; str[i] && str[i] != ' ' && str[i] != '\n'
+ && str[i] != '\t'; i++);
+ if(curr + i - 1 >= col4)
+ curr = col4;
+ break;
+ default:
+ printf("%c", *str);
+ curr++;
+ }
+ if(curr >= col4)
+ {
+ printf("\n");
+ curr = 0;
+ }
+ str++;
+ }
+ }
+ printf("\n");
+}
+
+void gaa_help(void)
+{
+ printf("PSKtool help\nUsage : psktool [options]\n");
+ __gaa_helpsingle('u', "username", "username ", "specify username.");
+ __gaa_helpsingle('p', "passwd", "FILE ", "specify a password file.");
+ __gaa_helpsingle('s', "keysize", "SIZE ", "specify the key size in bytes.");
+ __gaa_helpsingle('v', "version", "", "prints the program's version number");
+ __gaa_helpsingle('h', "help", "", "shows this help text");
+
+#line 100 "gaa.skel"
+}
+/* Copy of C area */
+
+#line 104 "gaa.skel"
+/* GAA HEADER */
+#ifndef GAA_HEADER_POKY
+#define GAA_HEADER_POKY
+
+typedef struct _gaainfo gaainfo;
+
+struct _gaainfo
+{
+#line 22 "psk.gaa"
+ int key_size;
+#line 19 "psk.gaa"
+ char *passwd;
+#line 16 "psk.gaa"
+ char *username;
+
+#line 114 "gaa.skel"
+};
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ int gaa(int argc, char *argv[], gaainfo *gaaval);
+
+ void gaa_help(void);
+
+ int gaa_file(const char *name, gaainfo *gaaval);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
+#line 135 "gaa.skel"
+
+/* C declarations */
+
+#define GAAERROR(x) \
+{ \
+gaa_error = 1; \
+return x; \
+}
+
+static char *gaa_current_option;
+static int gaa_error = 0;
+
+/* Generated by gaa */
+
+#include <string.h>
+#include <stdlib.h>
+
+
+#define GAA_OK -1
+
+#define GAA_ERROR_NOMATCH 0
+#define GAA_ERROR_NOTENOUGH_ARGS 1
+#define GAA_ERROR_INVALID_ARG 2
+#define GAA_ERROR_UNKNOWN 3
+
+#define GAA_NOT_AN_OPTION 0
+#define GAA_WORD_OPTION 1
+#define GAA_LETTER_OPTION 2
+#define GAA_MULTIPLE_OPTION 3
+
+#define GAA_REST 0
+#define GAA_NB_OPTION 5
+#define GAAOPTID_help 1
+#define GAAOPTID_version 2
+#define GAAOPTID_keysize 3
+#define GAAOPTID_passwd 4
+#define GAAOPTID_username 5
+
+#line 168 "gaa.skel"
+
+#define GAA_CHECK1STR(a,b) \
+if(a[0] == str[0]) \
+{ \
+ gaa_current_option = a; \
+ return b; \
+}
+
+#define GAA_CHECKSTR(a,b) \
+if(strcmp(a,str) == 0) \
+{ \
+ gaa_current_option = a; \
+ return b; \
+}
+
+#define GAA_TESTMOREARGS \
+if(!OK) \
+{ \
+while((gaa_last_non_option != gaa_index) && (gaa_arg_used[gaa_index] == 1)) \
+ gaa_index++; \
+if(gaa_last_non_option == gaa_index) \
+ return GAA_ERROR_NOTENOUGH_ARGS; \
+}
+
+#define GAA_TESTMOREOPTIONALARGS \
+if(!OK) \
+{ \
+while((gaa_last_non_option != gaa_index) && (gaa_arg_used[gaa_index] == 1)) \
+ gaa_index++; \
+if(gaa_last_non_option == gaa_index) \
+ OK = 1; \
+}
+
+#define GAA_FILL_2ARGS(target, func) \
+target = func(GAAargv[gaa_index]); \
+gaa_arg_used[gaa_index] = 1; \
+if(gaa_error == 1) \
+{ \
+ gaa_error = 0; \
+ return GAA_ERROR_INVALID_ARG; \
+}
+
+
+
+#define GAA_FILL(target, func, num) \
+if(!OK) \
+{ \
+target = func(GAAargv[gaa_index]); \
+gaa_arg_used[gaa_index] = 1; \
+if(gaa_error == 1) \
+{ \
+ gaa_error = 0; \
+ return GAA_ERROR_INVALID_ARG; \
+} \
+num = 1; \
+} \
+else \
+{ \
+num = 0; \
+}
+
+#define GAA_LIST_FILL(target, func, type ,num) \
+if(!OK) \
+{ \
+num = 0; \
+target = NULL; \
+if ( gaa_last_non_option - gaa_index > 0) \
+ target = gaa_malloc((gaa_last_non_option - gaa_index) * sizeof(type));\
+for(; gaa_index < gaa_last_non_option; gaa_index++) \
+{ \
+ if(gaa_arg_used[gaa_index] == 0) \
+ { \
+ GAA_FILL_2ARGS(target[num], func); \
+ num++; \
+ } \
+} \
+if(num == 0) \
+ return GAA_ERROR_NOTENOUGH_ARGS; \
+}
+
+#define GAA_OPTIONALLIST_FILL(target, func, type ,num) \
+if(!OK) \
+{ \
+num = 0; \
+target = NULL; \
+if ( gaa_last_non_option - gaa_index > 0) \
+ target = gaa_malloc((gaa_last_non_option - gaa_index) * sizeof(type));\
+for(; gaa_index < gaa_last_non_option; gaa_index++) \
+{ \
+ if(gaa_arg_used[gaa_index] == 0) \
+ { \
+ GAA_FILL_2ARGS(target[num], func); \
+ num++; \
+ } \
+} \
+}
+
+#define GAA_OBLIGAT(str) \
+k = 0; \
+for(i = 0; i < strlen(str); i++) \
+{ \
+ j = gaa_get_option_num(str + i, GAA_LETTER_OPTION); \
+ if(j == GAA_ERROR_NOMATCH) \
+ { \
+ printf("Error: invalid 'obligat' set\n"); \
+ exit(-1); \
+ } \
+ if(opt_list[j] == 1) \
+ k = 1; \
+} \
+if(k == 0) \
+{ \
+ if(strlen(str) == 1) \
+ printf("You must give the -%s option\n", str); \
+ else \
+ printf("You must give at least one option of '%s'\n", str); \
+ return 0; \
+}
+
+#define GAA_INCOMP(str) \
+k = 0; \
+for(i = 0; i < strlen(str); i++) \
+{ \
+ j = gaa_get_option_num(str + i, GAA_LETTER_OPTION); \
+ if(j == GAA_ERROR_NOMATCH) \
+ { \
+ printf("Error: invalid 'obligat' set\n"); \
+ exit(-1); \
+ } \
+ if(opt_list[j] == 1) \
+ k++; \
+} \
+if(k > 1) \
+{ \
+ printf("The options '%s' are incompatible\n", str); \
+ return 0; \
+}
+
+
+static char **GAAargv;
+static int GAAargc;
+static char *gaa_arg_used;
+static int gaa_processing_file = 0;
+static int inited = 0;
+
+static int gaa_getint(char *arg)
+{
+ int tmp;
+ char a;
+ if(sscanf(arg, "%d%c", &tmp, &a) < 1)
+ {
+ printf("Option %s: '%s' isn't an integer\n", gaa_current_option, arg);
+ GAAERROR(-1);
+ }
+ return tmp;
+}
+
+static char gaa_getchar(char *arg)
+{
+ if(strlen(arg) != 1)
+ {
+ printf("Option %s: '%s' isn't an character\n", gaa_current_option, arg);
+ GAAERROR(-1);
+ }
+ return arg[0];
+}
+
+static char* gaa_getstr(char *arg)
+{
+ return arg;
+}
+static float gaa_getfloat(char *arg)
+{
+ float tmp;
+ char a;
+ if(sscanf(arg, "%f%c", &tmp, &a) < 1)
+ {
+ printf("Option %s: '%s' isn't a float number\n", gaa_current_option, arg);
+ GAAERROR(-1);
+ }
+ return tmp;
+}
+/* option structures */
+
+struct GAAOPTION_keysize
+{
+ int arg1;
+ int size1;
+};
+
+struct GAAOPTION_passwd
+{
+ char* arg1;
+ int size1;
+};
+
+struct GAAOPTION_username
+{
+ char* arg1;
+ int size1;
+};
+
+#line 349 "gaa.skel"
+static int gaa_is_an_argument(char *str)
+{
+#ifdef GAA_WIN32
+ if(str[0] == '/' && str[1] != 0)
+ return GAA_MULTIPLE_OPTION;
+#endif
+ if(str[0] != '-')
+ return GAA_NOT_AN_OPTION;
+ if(str[1] == 0)
+ return GAA_NOT_AN_OPTION;
+ if(str[1] == '-')
+ {
+ if(str[2] != 0)
+ return GAA_WORD_OPTION;
+ else
+ return GAA_NOT_AN_OPTION;
+ }
+ if(str[2] == 0)
+ return GAA_LETTER_OPTION;
+ else
+ return GAA_MULTIPLE_OPTION;
+}
+
+static int gaa_get_option_num(char *str, int status)
+{
+ switch(status)
+ {
+ case GAA_LETTER_OPTION:
+ GAA_CHECK1STR("s", GAAOPTID_keysize);
+ GAA_CHECK1STR("p", GAAOPTID_passwd);
+ GAA_CHECK1STR("u", GAAOPTID_username);
+ case GAA_MULTIPLE_OPTION:
+#line 375 "gaa.skel"
+ GAA_CHECK1STR("h", GAAOPTID_help);
+ GAA_CHECK1STR("v", GAAOPTID_version);
+
+#line 277 "gaa.skel"
+ break;
+ case GAA_WORD_OPTION:
+ GAA_CHECKSTR("help", GAAOPTID_help);
+ GAA_CHECKSTR("version", GAAOPTID_version);
+ GAA_CHECKSTR("keysize", GAAOPTID_keysize);
+ GAA_CHECKSTR("passwd", GAAOPTID_passwd);
+ GAA_CHECKSTR("username", GAAOPTID_username);
+
+#line 281 "gaa.skel"
+ break;
+ default: break;
+ }
+ return GAA_ERROR_NOMATCH;
+}
+
+static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
+{
+ int OK = 0;
+ int gaa_last_non_option;
+ struct GAAOPTION_keysize GAATMP_keysize;
+ struct GAAOPTION_passwd GAATMP_passwd;
+ struct GAAOPTION_username GAATMP_username;
+
+#line 393 "gaa.skel"
+#ifdef GAA_REST_EXISTS
+ struct GAAREST GAAREST_tmp;
+#endif
+
+ opt_list[gaa_num] = 1;
+
+ for(gaa_last_non_option = gaa_index;
+ (gaa_last_non_option != GAAargc) && (gaa_is_an_argument(GAAargv[gaa_last_non_option]) == GAA_NOT_AN_OPTION);
+ gaa_last_non_option++);
+
+ if(gaa_num == GAA_REST)
+ {
+ gaa_index = 1;
+ gaa_last_non_option = GAAargc;
+ }
+
+ switch(gaa_num)
+ {
+ case GAAOPTID_help:
+ OK = 0;
+#line 26 "psk.gaa"
+{ gaa_help(); exit(0); ;};
+
+ return GAA_OK;
+ break;
+ case GAAOPTID_version:
+ OK = 0;
+#line 25 "psk.gaa"
+{ psktool_version(); exit(0); ;};
+
+ return GAA_OK;
+ break;
+ case GAAOPTID_keysize:
+ OK = 0;
+ GAA_TESTMOREARGS;
+ GAA_FILL(GAATMP_keysize.arg1, gaa_getint, GAATMP_keysize.size1);
+ gaa_index++;
+#line 23 "psk.gaa"
+{ gaaval->key_size = GAATMP_keysize.arg1 ;};
+
+ return GAA_OK;
+ break;
+ case GAAOPTID_passwd:
+ OK = 0;
+ GAA_TESTMOREARGS;
+ GAA_FILL(GAATMP_passwd.arg1, gaa_getstr, GAATMP_passwd.size1);
+ gaa_index++;
+#line 20 "psk.gaa"
+{ gaaval->passwd = GAATMP_passwd.arg1 ;};
+
+ return GAA_OK;
+ break;
+ case GAAOPTID_username:
+ OK = 0;
+ GAA_TESTMOREARGS;
+ GAA_FILL(GAATMP_username.arg1, gaa_getstr, GAATMP_username.size1);
+ gaa_index++;
+#line 17 "psk.gaa"
+{ gaaval->username = GAATMP_username.arg1 ;};
+
+ return GAA_OK;
+ break;
+
+#line 413 "gaa.skel"
+ default: break;
+ }
+ return GAA_ERROR_UNKNOWN;
+}
+
+int gaa(int argc, char **argv, gaainfo *gaaval)
+{
+ int tmp1, tmp2;
+ int i, j;
+ char *opt_list;
+
+ GAAargv = argv;
+ GAAargc = argc;
+
+ opt_list = (char*) gaa_malloc(GAA_NB_OPTION + 1);
+
+ for(i = 0; i < GAA_NB_OPTION + 1; i++)
+ opt_list[i] = 0;
+ /* initialization */
+ if(inited == 0)
+ {
+
+#line 28 "psk.gaa"
+{ gaaval->username=NULL; gaaval->passwd=NULL; gaaval->key_size = NULL; ;};
+
+ }
+ inited = 1;
+#line 438 "gaa.skel"
+ gaa_arg_used = NULL;
+
+ if (argc > 0) {
+ gaa_arg_used = gaa_malloc(argc * sizeof(char));
+ }
+
+ for(i = 1; i < argc; i++)
+ gaa_arg_used[i] = 0;
+ for(i = 1; i < argc; i++)
+ {
+ if(gaa_arg_used[i] == 0)
+ {
+ j = 0;
+ tmp1 = gaa_is_an_argument(GAAargv[i]);
+ switch(tmp1)
+ {
+ case GAA_WORD_OPTION:
+ j++;
+ case GAA_LETTER_OPTION:
+ j++;
+ tmp2 = gaa_get_option_num(argv[i]+j, tmp1);
+ if(tmp2 == GAA_ERROR_NOMATCH)
+ {
+ printf("Invalid option '%s'\n", argv[i]+j);
+ return 0;
+ }
+ switch(gaa_try(tmp2, i+1, gaaval, opt_list))
+ {
+ case GAA_ERROR_NOTENOUGH_ARGS:
+ printf("'%s': not enough arguments\n",gaa_current_option);
+ return 0;
+ case GAA_ERROR_INVALID_ARG:
+ printf("Invalid arguments\n");
+ return 0;
+ case GAA_OK:
+ break;
+ default:
+ printf("Unknown error\n");
+ }
+ gaa_arg_used[i] = 1;
+ break;
+ case GAA_MULTIPLE_OPTION:
+ for(j = 1; j < strlen(argv[i]); j++)
+ {
+ tmp2 = gaa_get_option_num(argv[i]+j, tmp1);
+ if(tmp2 == GAA_ERROR_NOMATCH)
+ {
+ printf("Invalid option '%c'\n", *(argv[i]+j));
+ return 0;
+ }
+ switch(gaa_try(tmp2, i+1, gaaval, opt_list))
+ {
+ case GAA_ERROR_NOTENOUGH_ARGS:
+ printf("'%s': not enough arguments\n",gaa_current_option);
+ return 0;
+ case GAA_ERROR_INVALID_ARG:
+ printf("Invalid arguments\n");
+ return 0;
+ case GAA_OK:
+ break;
+ default:
+ printf("Unknown error\n");
+ }
+ }
+ gaa_arg_used[i] = 1;
+ break;
+ default: break;
+ }
+ }
+ }
+if(gaa_processing_file == 0)
+{
+
+#line 507 "gaa.skel"
+#ifdef GAA_REST_EXISTS
+ switch(gaa_try(GAA_REST, 1, gaaval, opt_list))
+ {
+ case GAA_ERROR_NOTENOUGH_ARGS:
+ printf("Rest: not enough arguments\n");
+ return 0;
+ case GAA_ERROR_INVALID_ARG:
+ printf("Invalid arguments\n");
+ return 0;
+ case GAA_OK:
+ break;
+ default:
+ printf("Unknown error\n");
+ }
+#endif
+}
+ for(i = 1; i < argc; i++)
+ {
+ if(gaa_arg_used[i] == 0)
+ {
+ printf("Too many arguments\n");
+ return 0;
+ }
+ }
+ free(gaa_arg_used);
+ free(opt_list);
+ return -1;
+}
+
+struct gaastrnode
+{
+ char *str;
+ struct gaastrnode *next;
+};
+
+typedef struct gaastrnode gaa_str_node;
+
+static int gaa_internal_get_next_str(FILE *file, gaa_str_node *tmp_str, int argc)
+{
+ int pos_ini;
+ int a;
+ int i = 0, len = 0, newline = 0;
+
+ if(argc == 1) {
+ newline = 1;
+ len = 2;
+ }
+
+ a = fgetc( file);
+ if (a == EOF) return 0;
+
+ while(a == ' ' || a == 9 || a == '\n')
+ {
+ if(a == '\n')
+ {
+ newline=1;
+ len = 2;
+ }
+ a = fgetc( file);
+ if (a == EOF) return 0;
+ }
+
+ pos_ini = ftell(file) - 1;
+
+ while(a != ' ' && a != 9 && a != '\n')
+ {
+
+ len++;
+ a = fgetc( file);
+ if(a==EOF) return 0; //a = ' ';
+ }
+
+ len += 1;
+ tmp_str->str = gaa_malloc((len) * sizeof(char));
+
+ if(newline == 1)
+ {
+ tmp_str->str[0] = '-';
+ tmp_str->str[1] = '-';
+ i = 2;
+ }
+ else
+ {
+ i = 0;
+ }
+
+ fseek(file,pos_ini, SEEK_SET);
+ do
+ {
+ a = fgetc( file);
+
+ if (a == EOF) {
+ i+=2;
+ break;
+ }
+ tmp_str->str[i] = a;
+ i++;
+ }
+ while(a != ' ' && a != 9 && a != '\n' && i < len);
+
+ tmp_str->str[i - 1] = 0;
+
+ fseek(file,- 1, SEEK_CUR);
+/* printf("%d\n", ftell(file)); */
+
+ return -1;
+}
+
+int gaa_file(const char *name, gaainfo *gaaval)
+{
+ gaa_str_node *first_str, **tmp_str, *tmp_str2;
+ int rval, i;
+ char **argv;
+ int argc = 0;
+ FILE *file;
+
+ gaa_processing_file = 1;
+
+ if((file = fopen(name, "r")) == NULL)
+ {
+ printf("Couldn't open '%s' configuration file for reading\n", name);
+ return 1;
+ }
+
+ tmp_str = &first_str;
+ do
+ {
+ argc++;
+ *tmp_str = gaa_malloc(sizeof(gaa_str_node));
+
+ (*tmp_str)->str = NULL;
+ (*tmp_str)->next = NULL;
+
+ rval = gaa_internal_get_next_str(file, *tmp_str, argc);
+ tmp_str = &((*tmp_str)->next);
+ }
+ while(rval == -1);
+
+ if(rval == 1)
+ return 0;
+
+ argv = gaa_malloc((1 + argc) * sizeof(char*));
+
+ tmp_str2 = first_str;
+ argv[0] = "cfg";
+ for(i = 1; i < argc; i++)
+ {
+ argv[i] = tmp_str2->str;
+ tmp_str2 = tmp_str2->next;
+ }
+
+ rval = gaa(argc, argv, gaaval);
+ gaa_processing_file = 0;
+ return rval;
+}
diff --git a/src/psk-gaa.h b/src/psk-gaa.h
new file mode 100644
index 0000000000..88c5de5aed
--- /dev/null
+++ b/src/psk-gaa.h
@@ -0,0 +1,37 @@
+
+#line 104 "gaa.skel"
+/* GAA HEADER */
+#ifndef GAA_HEADER_POKY
+#define GAA_HEADER_POKY
+
+typedef struct _gaainfo gaainfo;
+
+struct _gaainfo
+{
+#line 22 "psk.gaa"
+ int key_size;
+#line 19 "psk.gaa"
+ char *passwd;
+#line 16 "psk.gaa"
+ char *username;
+
+#line 114 "gaa.skel"
+};
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ int gaa(int argc, char *argv[], gaainfo *gaaval);
+
+ void gaa_help(void);
+
+ int gaa_file(const char *name, gaainfo *gaaval);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/src/psk.c b/src/psk.c
new file mode 100644
index 0000000000..f930b07c88
--- /dev/null
+++ b/src/psk.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2005 Free Software Foundation
+ *
+ * This file is part of GNUTLS.
+ *
+ * GNUTLS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUTLS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <config.h>
+
+#define _MAX(x,y) (x>y?x:y)
+
+#ifndef ENABLE_PSK
+
+#include <stdio.h>
+
+
+int main(int argc, char **argv)
+{
+ printf("\nPSK not supported. This program is a dummy.\n\n");
+ return 1;
+};
+
+void psktool_version(void)
+{
+ fprintf(stderr, "GNU TLS dummy psktool.\n");
+}
+
+#else
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/extra.h>
+#include <psk-gaa.h>
+
+#include <gc.h> /* for randomize */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifndef _WIN32
+# include <pwd.h>
+# include <unistd.h>
+#else
+# include <windows.h>
+#endif
+
+static int write_key(const char *username, const char *key, int key_size, char *passwd_file);
+
+void psktool_version(void)
+{
+ fprintf(stderr, "GNU TLS psktool, ");
+ fprintf(stderr, "version %s. Libgnutls %s.\n", LIBGNUTLS_VERSION,
+ gnutls_check_version(NULL));
+}
+
+
+#define KPASSWD "/etc/passwd.psk"
+#define MAX_KEY_SIZE 64
+int main(int argc, char **argv)
+{
+ gaainfo info;
+ int ret;
+ struct passwd *pwd;
+ unsigned char key[MAX_KEY_SIZE];
+ char hex_key[MAX_KEY_SIZE*2 +1];
+ gnutls_datum dkey;
+ size_t hex_key_size = sizeof( hex_key);
+
+ if ((ret = gnutls_global_init()) < 0) {
+ fprintf(stderr, "global_init: %s\n", gnutls_strerror(ret));
+ exit(1);
+ }
+
+#ifdef HAVE_UMASK
+ umask(066);
+#endif
+
+ if (gaa(argc, argv, &info) != -1) {
+ fprintf(stderr, "Error in the arguments.\n");
+ return -1;
+ }
+
+ if (info.passwd == NULL)
+ info.passwd = KPASSWD;
+
+ if (info.username == NULL) {
+#ifndef _WIN32
+ pwd = getpwuid(getuid());
+
+ if (pwd == NULL) {
+ fprintf(stderr, "No such user\n");
+ return -1;
+ }
+
+ info.username = pwd->pw_name;
+#else
+ fprintf(stderr, "Please specify a user\n");
+ return -1;
+#endif
+ }
+
+ if ( info.key_size > MAX_KEY_SIZE) {
+ fprintf(stderr, "Key size is too long\n");
+ exit(1);
+ }
+
+ if (info.key_size < 1) info.key_size = 16;
+
+ ret = gc_pseudo_random( (char*)key, info.key_size);
+ if (ret != GC_OK) {
+ fprintf(stderr, "Not enough randomness\n");
+ exit(1);
+ }
+
+ printf("Generating a random key for user '%s'\n", info.username);
+
+ dkey.data = key;
+ dkey.size = info.key_size;
+ ret = gnutls_hex_encode( &dkey, hex_key, &hex_key_size);
+ if (ret < 0) {
+ fprintf(stderr, "HEX encoding error\n");
+ exit(1);
+ }
+
+ ret = write_key(info.username, hex_key, hex_key_size, info.passwd);
+ if (ret == 0)
+ printf("Key stored to %s\n", info.passwd);
+
+ return ret;
+}
+
+static int filecopy(char *src, char *dst)
+{
+ FILE *fd, *fd2;
+ char line[5 * 1024];
+ char *p;
+
+ fd = fopen(dst, "w");
+ if (fd == NULL) {
+ fprintf(stderr, "Cannot open '%s' for write\n", dst);
+ return -1;
+ }
+
+ fd2 = fopen(src, "r");
+ if (fd2 == NULL) {
+ /* empty file */
+ fclose(fd);
+ return 0;
+ }
+
+ line[sizeof(line) - 1] = 0;
+ do {
+ p = fgets(line, sizeof(line) - 1, fd2);
+ if (p == NULL)
+ break;
+
+ fputs(line, fd);
+ } while (1);
+
+ fclose(fd);
+ fclose(fd2);
+
+ return 0;
+}
+
+static int write_key(const char *username, const char *key, int key_size,
+ char *passwd_file)
+{
+ FILE *fd;
+ char line[5 * 1024];
+ char *p, *pp;
+ char tmpname[1024];
+
+
+ /* delete previous entry */
+ struct stat st;
+ FILE *fd2;
+ int put;
+
+ if (strlen(passwd_file) > sizeof(tmpname) + 5) {
+ fprintf(stderr, "file '%s' is tooooo long\n", passwd_file);
+ return -1;
+ }
+ strcpy(tmpname, passwd_file);
+ strcat(tmpname, ".tmp");
+
+ if (stat(tmpname, &st) != -1) {
+ fprintf(stderr, "file '%s' is locked\n", tmpname);
+ return -1;
+ }
+
+ if (filecopy(passwd_file, tmpname) != 0) {
+ fprintf(stderr, "Cannot copy '%s' to '%s'\n",
+ passwd_file, tmpname);
+ return -1;
+ }
+
+ fd = fopen(passwd_file, "w");
+ if (fd == NULL) {
+ fprintf(stderr, "Cannot open '%s' for write\n", passwd_file);
+ remove(tmpname);
+ return -1;
+ }
+
+ fd2 = fopen(tmpname, "r");
+ if (fd2 == NULL) {
+ fprintf(stderr, "Cannot open '%s' for read\n", tmpname);
+ remove(tmpname);
+ return -1;
+ }
+
+ put = 0;
+ do {
+ p = fgets(line, sizeof(line) - 1, fd2);
+ if (p == NULL)
+ break;
+
+ pp = strchr(line, ':');
+ if (pp == NULL)
+ continue;
+
+ if (strncmp
+ (p, username,
+ _MAX(strlen(username), (unsigned int) (pp - p))) == 0) {
+ put = 1;
+ fprintf(fd, "%s:%s\n", username, key);
+ } else {
+ fputs(line, fd);
+ }
+ } while (1);
+
+ if (put == 0) {
+ fprintf(fd, "%s:%s\n", username, key);
+ }
+
+ fclose(fd);
+ fclose(fd2);
+
+ remove(tmpname);
+
+
+ return 0;
+}
+
+#endif /* ENABLE_PSK */
diff --git a/src/psk.gaa b/src/psk.gaa
new file mode 100644
index 0000000000..24660b1487
--- /dev/null
+++ b/src/psk.gaa
@@ -0,0 +1,29 @@
+#{
+
+/* C declarations */
+
+#include <config.h>
+#ifdef _WIN32
+# include <io.h>
+#endif
+
+void psktool_version(void);
+
+#}
+
+helpnode "PSKtool help\nUsage : psktool [options]"
+
+#char *username;
+option (u,username) STR "username" { $username = $1 } "specify username."
+
+#char *passwd;
+option (p, passwd) STR "FILE" { $passwd = $1 } "specify a password file."
+
+#int key_size;
+option (s, keysize) INT "SIZE" { $key_size = $1 } "specify the key size in bytes."
+
+option (v, version) { psktool_version(); exit(0); } "prints the program's version number"
+option (h, help) { gaa_help(); exit(0); } "shows this help text"
+
+init { $username=NULL; $passwd=NULL; $key_size = NULL; }
+
diff --git a/src/serv.c b/src/serv.c
index 4ff6a78a9a..7210f03bc0 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -52,6 +52,7 @@ int verbose;
static int nodb;
int require_cert;
+char *psk_passwd;
char *srp_passwd;
char *srp_passwd_conf;
char *pgp_keyring;
@@ -100,9 +101,10 @@ char *x509_crlfile = NULL;
#define RENEGOTIATE
/* These are global */
-gnutls_srp_server_credentials srp_cred = NULL;
-gnutls_anon_server_credentials dh_cred = NULL;
-gnutls_certificate_credentials cert_cred = NULL;
+gnutls_srp_server_credentials_t srp_cred = NULL;
+gnutls_psk_server_credentials_t psk_cred = NULL;
+gnutls_anon_server_credentials_t dh_cred = NULL;
+gnutls_certificate_credentials_t cert_cred = NULL;
const int ssl_session_cache = 128;
@@ -206,7 +208,7 @@ static void read_dh_params(void)
tmpdata[size] = 0;
fclose(fd);
- params.data = tmpdata;
+ params.data = (unsigned char*)tmpdata;
params.size = size;
size =
@@ -268,6 +270,7 @@ int protocol_priority[PRI_MAX] =
{ GNUTLS_TLS1_1, GNUTLS_TLS1, GNUTLS_SSL3, 0 };
int kx_priority[PRI_MAX] =
{ GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP,
+ GNUTLS_KX_PSK,
/* Do not use anonymous authentication, unless you know what that means */
GNUTLS_KX_SRP_DSS, GNUTLS_KX_SRP_RSA, GNUTLS_KX_ANON_DH,
GNUTLS_KX_RSA_EXPORT, 0
@@ -316,6 +319,9 @@ gnutls_session initialize_session(void)
if (srp_cred != NULL)
gnutls_credentials_set(session, GNUTLS_CRD_SRP, srp_cred);
+ if (psk_cred != NULL)
+ gnutls_credentials_set(session, GNUTLS_CRD_PSK, psk_cred);
+
if (cert_cred != NULL)
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cert_cred);
@@ -339,7 +345,7 @@ char *peer_print_info(gnutls_session session, int *ret_length,
{
const char *tmp;
unsigned char sesid[32];
- int sesid_size, i;
+ size_t i, sesid_size;
char *http_buffer = malloc(5 * 1024 + strlen(header));
gnutls_kx_algorithm kx_alg;
@@ -394,6 +400,13 @@ char *peer_print_info(gnutls_session session, int *ret_length,
}
#endif
+#ifdef ENABLE_PSK
+ if (kx_alg == GNUTLS_KX_PSK) {
+ sprintf(tmp2, "<p>Connected as user '%s'.</p>\n",
+ gnutls_psk_server_get_username(session));
+ }
+#endif
+
#ifdef ENABLE_ANON
if (kx_alg == GNUTLS_KX_ANON_DH) {
sprintf(tmp2,
@@ -726,6 +739,22 @@ int main(int argc, char **argv)
}
#endif
+ /* this is a password file
+ */
+#ifdef ENABLE_PSK
+ if (psk_passwd != NULL) {
+ gnutls_psk_allocate_server_credentials(&psk_cred);
+
+ if ((ret =
+ gnutls_psk_set_server_credentials_file(psk_cred, psk_passwd)) < 0) {
+ /* only exit is this function is not disabled
+ */
+ fprintf(stderr, "Error while setting PSK parameters\n");
+ GERR(ret);
+ }
+ }
+#endif
+
#ifdef ENABLE_ANON
gnutls_anon_allocate_server_credentials(&dh_cred);
if (generate != 0)
@@ -1014,6 +1043,10 @@ int main(int argc, char **argv)
gnutls_srp_free_server_credentials(srp_cred);
#endif
+#ifdef ENABLE_PSK
+ gnutls_psk_free_server_credentials(psk_cred);
+#endif
+
#ifdef ENABLE_ANON
gnutls_anon_free_server_credentials(dh_cred);
#endif
@@ -1070,6 +1103,8 @@ void gaa_parser(int argc, char **argv)
srp_passwd = info.srp_passwd;
srp_passwd_conf = info.srp_passwd_conf;
+ psk_passwd = info.psk_passwd;
+
pgp_keyring = info.pgp_keyring;
pgp_trustdb = info.pgp_trustdb;
diff --git a/src/serv.gaa b/src/serv.gaa
index d19071111e..6767832480 100644
--- a/src/serv.gaa
+++ b/src/serv.gaa
@@ -67,6 +67,9 @@ option (x509dsacertfile) STR "FILE" { $x509_dsacertfile = $1 } "Alternative X.50
#int require_cert;
option (require-cert) { $require_cert = 1 } "Require a valid certificate."
+#char *psk_passwd;
+option (pskpasswd) STR "FILE" { $psk_passwd = $1 } "PSK password file to use."
+
#char *srp_passwd;
option (srppasswd) STR "FILE" { $srp_passwd = $1 } "SRP password file to use."
@@ -114,6 +117,6 @@ init { $generate=0; $port=5556; $http=0; $ciphers=NULL;
$x509_dsakeyfile=NULL; $x509_dsacertfile=NULL;
$srp_passwd=NULL; $srp_passwd_conf=NULL; $quiet = 0;
$pgp_trustdb=NULL; $pgp_keyring=NULL; $fmtder = 0;
- $dh_params_file=NULL; $debug=0; $require_cert = 0; }
+ $dh_params_file=NULL; $debug=0; $require_cert = 0; $psk_passwd = 0; }