[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
shishi lib/Makefile.am lib/internal.h lib/netio...
From: |
shishi-commit |
Subject: |
shishi lib/Makefile.am lib/internal.h lib/netio... |
Date: |
Mon, 22 Sep 2003 20:19:58 -0400 |
CVSROOT: /cvsroot/shishi
Module name: shishi
Branch:
Changes by: Simon Josefsson <address@hidden> 03/09/22 20:19:58
Modified files:
lib : Makefile.am internal.h netio.c
. : configure.ac
src : shishid.c
doc : shishi.texi
Added files:
lib : starttls.c
Log message:
Add experimental STARTTLS support.
CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/shishi/shishi/lib/starttls.c?rev=1.1
http://savannah.gnu.org/cgi-bin/viewcvs/shishi/shishi/lib/Makefile.am.diff?tr1=1.54&tr2=1.55&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/shishi/shishi/lib/internal.h.diff?tr1=1.66&tr2=1.67&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/shishi/shishi/lib/netio.c.diff?tr1=1.30&tr2=1.31&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/shishi/shishi/configure.ac.diff?tr1=1.91&tr2=1.92&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/shishi/shishi/src/shishid.c.diff?tr1=1.50&tr2=1.51&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/shishi/shishi/doc/shishi.texi.diff?tr1=1.84&tr2=1.85&r1=text&r2=text
Patches:
Index: shishi/configure.ac
diff -u shishi/configure.ac:1.91 shishi/configure.ac:1.92
--- shishi/configure.ac:1.91 Sun Sep 21 16:39:21 2003
+++ shishi/configure.ac Mon Sep 22 20:19:58 2003
@@ -284,16 +284,17 @@
# Check for gnutls.
AC_ARG_ENABLE(tls,
- AC_HELP_STRING([--enable-tls], [enable unfinished TLS support]),
- tls=$enableval, tls=no)
+ AC_HELP_STRING([--enable-tls], [enable non-standard TLS support]),
+ tls=$enableval, tls=yes)
if test "$tls" != "no"; then
AM_PATH_LIBGNUTLS(0.8.8, tls=yes, tls=no)
fi
+AC_MSG_CHECKING([if non-standard TLS support should be enabled])
+AC_MSG_RESULT($tls)
if test "$tls" != "no"; then
- AC_DEFINE(USE_GNUTLS, 1, [Define to 1 if you want TLS.])
+ AC_DEFINE(USE_STARTTLS, 1, [Define to 1 if you want STARTTLS.])
fi
-AC_MSG_CHECKING([if unfinished TLS support should be enabled])
-AC_MSG_RESULT($tls)
+AM_CONDITIONAL(STARTTLS, test "$tls" != "no")
# Check for gtk-doc.
AC_ARG_WITH(html-dir, [ --with-html-dir=PATH path to installed docs ])
Index: shishi/doc/shishi.texi
diff -u shishi/doc/shishi.texi:1.84 shishi/doc/shishi.texi:1.85
--- shishi/doc/shishi.texi:1.84 Sun Sep 21 09:30:38 2003
+++ shishi/doc/shishi.texi Mon Sep 22 20:19:58 2003
@@ -72,6 +72,7 @@
Appendices
+* Protocol Extensions:: Description of protocol extensions used.
* Copying This Manual:: How you can copy and share this manual.
* Copying:: How you can copy and share the source.
@@ -2409,6 +2410,155 @@
@c **********************************************************
@c ******************* Appendices *************************
@c **********************************************************
+
address@hidden Protocol Extensions
address@hidden Protocol Extensions
+
+This appendix specifies the non-standard protocol elements implemented
+by Shishi.
+
address@hidden
+* STARTTLS protected KDC exchanges:: How Shishi talks to KDC protected by
TLS.
address@hidden menu
+
address@hidden STARTTLS protected KDC exchanges
address@hidden STARTTLS protected KDC exchanges
+
+Shishi is able to ``upgrade'' TCP communications with the KDC to use
+the Transport Layer Security (TLS) protocol. The TLS protocol offers
+integrity and privacy protected exchanges. TLS also offers
+authentication using username and passwords, X.509 certificates, or
+OpenPGP certificates. Kerberos 5 claims to offer some of these
+features, although it is not as rich as the TLS protocol. An
+inconclusive list of the motivation for using TLS is given below.
+
address@hidden @bullet
+
address@hidden Server authentication of the KDC to the client.
+In traditional Kerberos 5, KDC authentication is only proved as a side
+effect that the KDC knows your encryption key (i.e., your password).
+
address@hidden Client authentication against KDC.
+Kerberos 5 assume the user knows a key (usually in the form of a
+password). Sometimes external factors make this hard to fulfill. In
+some situations, users are equipped with smart cards with a RSA
+authentication key. In others, users have a OpenPGP client on their
+desktop, with a public OpenPGP key known to the server. In some
+situations, the policy may be that password authentication may only be
+done through SRP.
+
address@hidden Kerberos exchanges are privacy protected.
+Part of many Kerberos packets are transfered without privacy
+protection (i.e., encryption). That part contains information, such
+as the client principal name, the server principal name, the
+encryption types supported by the client, the lifetime of tickets,
+etc. Revealing such information is, in some threat models, considered
+a problem. Thus, this enables ``anonymity''.
+
address@hidden Prevents downgrade attacks affecting encryption types.
+The encryption type of the ticket in KDC-REQ are sent in the clear in
+Kerberos 5. This allows an attacker to replace the encryption type
+with a compromised mechanisms, e.g. 56-bit DES. Since clients in
+general cannot know the encryption types other servers support, it is
+difficult for the client to detect if there was a man-in-the-middle or
+if the remote server simply did not support a stronger mechanism.
+Clients may chose to refuse 56-bit DES altogether, but in some
+environments this leads to operational difficulties.
+
address@hidden TLS is well-proved and the protocol is studied by many parties.
+This is an advantage in network design, where TLS is often already
+assumed as part of the solution since it is used to protect HTTP,
+IMAP, SMTP etc. In some threat models, the designer prefer to reduce
+the number of protocols that can hurt the overall system security if
+they are compromised.
+
address@hidden itemize
+
+Other reasons for using TLS exists.
+
address@hidden TCP/IP transport with TLS upgrade (STARTTLS)
+
+RFC 1510bis requires Kerberos servers (KDCs) to accept TCP requests.
+Each request and response is prefixed by a 4 octet integer in network
+byte order, indicating the length of the packet. The high bit of the
+length was reserved for future expansion, and servers that do not
+understand how to interpret a set high bit must return a
address@hidden with a @code{KRB_ERR_FIELD_TOOLONG} and close the TCP
+stream.
+
+The TCP/IP transport with TLS upgrade (STARTTLS) uses this reserved
+bit as follows. First we define a new extensible typed hole for
+Kerberos 5 messages, because we used the only reserved bit. It is
+thus prudent to offer future extensions on our proposal. Secondly we
+reserve two values in this new typed hole, and described how they are
+used to implement STARTTLS.
+
address@hidden Extensible typed hole based on reserved high bit
+
+When the high bit is set, the remaining 31 bits of the 4 octets are
+treated as an extensible typed hole, and thus form a 31 bit integer
+enumerating various extensions. Each of the values indicate a
+specific extended operation mode, two of which are used and defined
+here, and the rest are left for others to use. If the KDC do not
+understand a requested extension, it MUST return a @code{KRB-ERROR}
+with a @code{KRB_ERR_FIELD_TOOLONG} value and close the TCP stream,
+where the 4 octet length integer MUST have the high bit set, to
+indicate support for the extensible typed hole construct itself, and
+the remaining 31 bits indicate the length of the packet, as normal.
+
+Meaning of the 31 lower bits in the 4 octet field, when the high bit
+is set:
+
address@hidden
+ 0 RESERVED.
+ 1 STARTTLS requested by client.
+ 2 STARTTLS request accepted by server.
+ 3...2147483647 AVAILABLE for registration (via address@hidden).
+ 2147483648 RESERVED.
address@hidden verbatim
+
address@hidden STARTTLS requested by client (extension mode 1)
+
+When this is sent by the client, the client is requesting the server
+to start TLS negotiation on the TCP stream. The client MUST NOT start
+TLS negotiation immediately. The client should wait for either a
+KRB-ERROR (sent normally, prefixed by a 4 octet length integer)
+indicating it does not understand the set high bit, or 4 octet which
+is to interpreted as an integer in network byte order, where the high
+bit is set and the remaining 31 bit are interpreted as an integer
+specifying the ``STARTTLS request accepted by server''. In the first
+case, the client infer that the server do not understand (or wish to
+support) STARTTLS, and can re-try using normal TCP, if unprotected
+Kerberos 5 exchanges are allowed by client policy. In the latter
+case, it should invoke TLS negotiation on the stream. If any other
+data is received, the client MUST close the TCP stream.
+
address@hidden STARTTLS request accepted by server (extension mode 2)
+
+This 4 octet message should be sent by the server when it has received
+the previous 4 octet message. The message is an acknowledgment of the
+client's request to initiate STARTTLS on the channel. The server MUST
+then invoke a TLS negotiation.
+
address@hidden Proceeding after successful TLS negotiation
+
+If the TLS negotiation ended successfully, possibly also considering
+client or server policies, the exchange within the TLS protected
+stream is performed like normal UDP Kerberos 5 exchanges, i.e., there
+is no TCP 4 octet length field before each packet.
+
+The server MAY consider the authentication performed by the TLS
+exchange as sufficient to issue Kerberos 5 tickets to the client,
+without requiring pre-authentication or the like. However, it is not
+an error to carry out pre-authentication as well. We are currently
+experimenting with this mode of operation.
+
address@hidden Proceeding after failed TLS negotiation
+
+If the TLS negotiation fails, possibly due to client or server policy
+(e.g., inadequate support of encryption types in TLS, or lack of
+client or server authentication) the entity that detect the failure
+should abort or re-try as appropriate, up to local policy.
@node Copying This Manual
@appendix Copying This Manual
Index: shishi/lib/Makefile.am
diff -u shishi/lib/Makefile.am:1.54 shishi/lib/Makefile.am:1.55
--- shishi/lib/Makefile.am:1.54 Sat Sep 13 07:43:47 2003
+++ shishi/lib/Makefile.am Mon Sep 22 20:19:57 2003
@@ -71,6 +71,9 @@
if LIBGCRYPT
libshishi_la_SOURCES += libgcrypt.c
endif
+if STARTTLS
+libshishi_la_SOURCES += starttls.c
+endif
libshishi_la_LIBADD = @LIBGCRYPT_LIBS@ @CRYPTO_LIBS@ \
@LTLIBINTL@ ../gl/libfoo.la @LIBTASN1_LIBS@ @LIBGNUTLS_LIBS@
libshishi_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
Index: shishi/lib/internal.h
diff -u shishi/lib/internal.h:1.66 shishi/lib/internal.h:1.67
--- shishi/lib/internal.h:1.66 Sat Sep 20 07:06:10 2003
+++ shishi/lib/internal.h Mon Sep 22 20:19:57 2003
@@ -264,6 +264,11 @@
shishi_asn1_integer2_field (Shishi * handle,
Shishi_asn1 node, unsigned long *i,
const char *field);
+int
+_shishi_sendrecv_tls (Shishi * handle,
+ struct sockaddr *addr,
+ const char *indata, int inlen,
+ char **outdata, int *outlen, int timeout);
/* utils.c */
extern void _shishi_escapeprint (const char *str, int len);
Index: shishi/lib/netio.c
diff -u shishi/lib/netio.c:1.30 shishi/lib/netio.c:1.31
--- shishi/lib/netio.c:1.30 Sat Sep 6 15:57:16 2003
+++ shishi/lib/netio.c Mon Sep 22 20:19:57 2003
@@ -182,179 +182,33 @@
return SHISHI_OK;
}
-#ifdef USE_GNUTLS
-
-#include <gnutls/gnutls.h>
-
-/* XXX this is bogus, we should do a STARTTLS approach instead.
-
- I.e., first send KDC-REQ in clear with PA-STARTTLS preauth data,
- and if KDC doesn't reject it, start tls on that session.
- For udp we shouldn't do anything at all.
-
- Also need to add code to map client certificate X.509 into
- pre authenticated principal.
-
- Derive Kerberos EncKDCRepPart key from TLS PRF? Hm.
-
- Simpler: Use leading reserved bit in TCP length field to mean
- STARTTLS. (Probably better to have it mean that a new octet is
- present, and that a 0 in that field means STARTTLS, and all other
- fields are reserved, for future extensions.)
-*/
-
-static int
-shishi_sendrecv_tls (Shishi * handle,
- struct sockaddr *addr,
- const char *indata, int inlen,
- char **outdata, int *outlen, int timeout)
-{
- char tmpbuf[BUFSIZ]; /* XXX can we do without it?
- MSG_PEEK|MSG_TRUNC doesn't work for udp.. */
- int i;
- int sockfd;
- int ret;
- gnutls_session session;
- gnutls_certificate_credentials xcred;
- /* Allow connections to servers that have OpenPGP keys as well.
- */
- const int cert_type_priority[3] = { GNUTLS_CRT_X509,
- GNUTLS_CRT_OPENPGP, 0
- };
-
- sockfd = socket (AF_INET, SOCK_STREAM, 0);
- if (sockfd < 0)
- {
- shishi_error_set (handle, strerror (errno));
- return SHISHI_SOCKET_ERROR;
- }
-
- if (connect (sockfd, addr, sizeof (*addr)) != 0)
- {
- shishi_error_set (handle, strerror (errno));
- close (sockfd);
- return SHISHI_CONNECT_ERROR;
- }
-
- gnutls_global_init ();
-
- /* X509 stuff */
- gnutls_certificate_allocate_credentials (&xcred);
-
- /* set's the trusted cas file
- */
- //gnutls_certificate_set_x509_trust_file(xcred, CAFILE, GNUTLS_X509_FMT_PEM);
- /* Initialize TLS session
- */
- gnutls_init (&session, GNUTLS_CLIENT);
-
- /* Use default priorities */
- gnutls_set_default_priority (session);
- gnutls_certificate_type_set_priority (session, cert_type_priority);
-
- /* put the x509 credentials to the current session
- */
- gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
-
- gnutls_transport_set_ptr (session, (gnutls_transport_ptr) sockfd);
-
- /* Perform the TLS handshake
- */
- ret = gnutls_handshake (session);
-
- if (ret < 0)
- {
- fprintf (stderr, "*** Handshake failed\n");
- gnutls_perror (ret);
- }
- else
- {
- printf ("- Handshake was completed\n");
- }
-
- tmpbuf[3] = inlen & 0xFF;
- tmpbuf[2] = (inlen >> 8) & 0xFF;
- tmpbuf[1] = (inlen >> 16) & 0xFF;
- tmpbuf[0] = (inlen >> 24) & 0xFF;
-
- gnutls_record_send (session, tmpbuf, 4);
-
- gnutls_record_send (session, indata, inlen);
-
- ret = gnutls_record_recv (session, tmpbuf, sizeof (tmpbuf));
- if (ret == 0)
- {
- printf ("- Peer has closed the TLS connection\n");
- }
- else if (ret < 0)
- {
- fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret));
- }
- else if (ret > 0)
- {
- printf ("- Received %d bytes: ", ret);
- for (i = 0; i < ret; i++)
- {
- fputc (tmpbuf[i], stdout);
- }
- fputs ("\n", stdout);
- }
- gnutls_bye (session, GNUTLS_SHUT_RDWR);
-
- shutdown (sockfd, SHUT_RDWR); /* no more receptions */
-
- if (close (sockfd) != 0)
- {
- shishi_error_set (handle, strerror (errno));
- return SHISHI_CLOSE_ERROR;
- }
-
- gnutls_deinit (session);
-
- gnutls_certificate_free_credentials (xcred);
-
- gnutls_global_deinit ();
-
- *outlen = ret - 4;
- *outdata = xmalloc (*outlen);
- memcpy (*outdata, tmpbuf + 4, *outlen);
-
- return SHISHI_OK;
-}
-
-#else
-
-static int
-shishi_sendrecv_tls (Shishi * handle,
- struct sockaddr *addr,
- const char *indata, int inlen,
- char **outdata, int *outlen, int timeout)
-{
- return !SHISHI_OK;
-}
-
-#endif
-
static int
shishi_kdc_sendrecv_1 (Shishi * handle, struct Shishi_kdcinfo *ki,
const char *indata, size_t inlen,
char **outdata, size_t * outlen)
{
+ char *protname = ki->protocol == TCP ? "tcp" : "udp";
int rc;
+#ifdef USE_STARTTLS
+ if (ki->protocol == TLS)
+ protname = "tls";
+#endif
+
if (VERBOSE (handle))
printf ("Sending to %s (%s) via %s...\n", ki->name,
inet_ntoa (((struct sockaddr_in *) &ki->sockaddress)->sin_addr),
- ki->protocol == TCP ? "tcp" : ki->protocol ==
- TLS ? "tls" : "udp");
+ protname);
switch (ki->protocol)
{
+#ifdef USE_STARTTLS
case TLS:
- rc = shishi_sendrecv_tls (handle, &ki->sockaddress,
- indata, inlen, outdata, outlen,
- handle->kdctimeout);
+ rc = _shishi_sendrecv_tls (handle, &ki->sockaddress,
+ indata, inlen, outdata, outlen,
+ handle->kdctimeout);
break;
+#endif
case TCP:
rc = shishi_sendrecv_tcp (handle, &ki->sockaddress,
Index: shishi/src/shishid.c
diff -u shishi/src/shishid.c:1.50 shishi/src/shishid.c:1.51
--- shishi/src/shishid.c:1.50 Sat Sep 13 09:04:58 2003
+++ shishi/src/shishid.c Mon Sep 22 20:19:58 2003
@@ -114,6 +114,10 @@
#include <syslog.h>
#endif
+#ifdef USE_STARTTLS
+#include <gnutls/gnutls.h>
+#endif
+
#include <shishi.h>
#include <argp.h>
@@ -214,7 +218,7 @@
if (arguments->listenspec == NULL)
argp_error (state, "Fatal memory allocation error");
ls = &arguments->listenspec[arguments->nlistenspec - 1];
- memset (ls, 0, sizeof(*ls));
+ memset (ls, 0, sizeof (*ls));
ls->str = strdup (val);
ls->bufpos = 0;
sin = (struct sockaddr_in *) &ls->addr;
@@ -485,7 +489,7 @@
static int
asreq (Shishi * handle, struct arguments *arg,
- Shishi_asn1 kdcreq, char **out, size_t *outlen)
+ Shishi_asn1 kdcreq, char **out, size_t * outlen)
{
Shishi_as *as;
int rc;
@@ -685,7 +689,7 @@
static int
tgsreq (Shishi * handle, struct arguments *arg,
- Shishi_asn1 kdcreq, char **out, size_t *outlen)
+ Shishi_asn1 kdcreq, char **out, size_t * outlen)
{
Shishi_tgs *tgs;
int rc;
@@ -874,6 +878,40 @@
return 0;
}
+
+#define KEYFILE "key.pem"
+#define CERTFILE "cert.pem"
+#define CAFILE "ca.pem"
+#define CRLFILE "crl.pem"
+
+/* This is a sample TLS 1.0 echo server.
+ */
+
+
+#define SA struct sockaddr
+#define SOCKET_ERR(err,s) if(err==-1) {perror(s);return(1);}
+#define MAX_BUF 1024
+#define PORT 5556 /* listen to 5556 port */
+#define DH_BITS 1024
+
+static gnutls_dh_params dh_params;
+
+static int
+generate_dh_params (void)
+{
+
+ /* Generate Diffie Hellman parameters - for use with DHE
+ * kx algorithms. These should be discarded and regenerated
+ * once a day, once a week or once a month. Depending on the
+ * security requirements.
+ */
+ gnutls_dh_params_init (&dh_params);
+ gnutls_dh_params_generate2 (dh_params, DH_BITS);
+
+ return 0;
+}
+
+
static int
kdc_loop (Shishi * handle, struct arguments *arg)
{
@@ -966,9 +1004,90 @@
printf ("Has %d bytes from %s\n", ls->bufpos, ls->str);
+#ifdef USE_STARTTLS
+ if (arg->listenspec[i].type == SOCK_STREAM &&
+ ls->bufpos == 4 &&
+ memcmp (ls->buf, "\x70\x00\x00\x01", 4) == 0)
+ {
+ int err, i;
+ int ret;
+ struct sockaddr_in sa_serv;
+ struct sockaddr_in sa_cli;
+ int client_len;
+ char topbuf[512];
+ gnutls_session session;
+ char buffer[MAX_BUF + 1];
+ int optval = 1;
+ const int kx_prio[] = { GNUTLS_KX_ANON_DH, 0 };
+ gnutls_anon_server_credentials anoncred;
+
+ if (!arg->silent)
+ printf ("Trying to upgrade to TLS...\n");
+
+ sent_bytes = sendto (ls->sockfd, "\x70\x00\x00\x02", 4,
+ 0, &addr, length);
+
+ gnutls_anon_allocate_server_credentials (&anoncred);
+ gnutls_anon_set_server_dh_params (anoncred, dh_params);
+ gnutls_init (&session, GNUTLS_SERVER);
+ gnutls_set_default_priority (session);
+ gnutls_kx_set_priority (session, kx_prio);
+ gnutls_credentials_set (session, GNUTLS_CRD_ANON,
+ anoncred);
+ gnutls_certificate_server_set_request (session,
+ GNUTLS_CERT_REQUEST);
+ gnutls_dh_set_prime_bits (session, DH_BITS);
+ gnutls_transport_set_ptr (session,
+ (gnutls_transport_ptr) ls->
+ sockfd);
+
+ ret = gnutls_handshake (session);
+ if (ret < 0)
+ {
+ gnutls_deinit (session);
+ if (!arg->silent)
+ printf ("Handshake has failed %d...\n",
+ gnutls_strerror (ret));
+ }
+
+ if (!arg->silent)
+ printf ("TLS successful\n");
+
+ bzero (buffer, MAX_BUF + 1);
+ ret = gnutls_record_recv (session, buffer, MAX_BUF);
+
+ if (ret == 0)
+ {
+ printf ("- Peer has closed the GNUTLS connection\n");
+ }
+ else if (ret < 0)
+ {
+ printf ("*** Corrupted data(%d). Closing.\n\n", ret);
+ }
+ else if (ret > 0)
+ {
+ char *p;
+ size_t plen;
+
+ process (handle, arg, buffer, ret, &p, &plen);
+
+ printf ("TLS process %d sending %d\n", ret, plen);
+
+ gnutls_record_send (session, p, plen);
+
+ if (p != fatal_krberror)
+ free (p);
+ }
+ ls->bufpos = 0;
+ gnutls_bye (session, GNUTLS_SHUT_WR);
+ gnutls_deinit (session);
+ gnutls_global_deinit ();
+ }
+ else
+#endif
if (arg->listenspec[i].type == SOCK_DGRAM ||
- (ls->bufpos > 4 &&
- ntohl (*(int *) ls->buf) + 4 == ls->bufpos))
+ (ls->bufpos > 4 &&
+ ntohl (*(int *) ls->buf) + 4 == ls->bufpos))
{
char *p;
size_t plen;
@@ -1123,6 +1242,17 @@
{
Shishi *handle;
int rc;
+
+#ifdef USE_STARTTLS
+ if (!arg->silent)
+ printf ("Initializing GNUTLS...\n");
+ fflush (stdout);
+ gnutls_global_init ();
+ generate_dh_params ();
+ if (!arg->silent)
+ printf ("Initializing GNUTLS...done\n");
+ fflush (stdout);
+#endif
rc = shishi_init_server_with_paths (&handle, arg->cfgfile);
if (rc != SHISHI_OK)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- shishi lib/Makefile.am lib/internal.h lib/netio...,
shishi-commit <=