diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-04-09 09:25:11 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-04-09 09:25:11 +0200 |
commit | 08a1b04b3d049a4a44132c0bce0c017c0c70f892 (patch) | |
tree | 3949352f7e10f386712c91d7aa8f9d8a0178d478 | |
parent | 078b384417a34d3eedab9179f71bfcbe9052a3e2 (diff) | |
download | gnutls-08a1b04b3d049a4a44132c0bce0c017c0c70f892.tar.gz |
Added documentation for Datagram TLS.
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | doc/cha-gtls-app.texi | 10 | ||||
-rw-r--r-- | doc/cha-intro-tls.texi | 48 | ||||
-rw-r--r-- | doc/examples/Makefile.am | 4 | ||||
-rw-r--r-- | doc/examples/ex-client-udp.c | 120 | ||||
-rw-r--r-- | doc/examples/udp.c | 58 | ||||
-rw-r--r-- | lib/gnutls_state.c | 6 |
7 files changed, 235 insertions, 12 deletions
diff --git a/.gitignore b/.gitignore index ed50eba4d6..bd5cdd16a7 100644 --- a/.gitignore +++ b/.gitignore @@ -436,3 +436,4 @@ doc/examples/ex-cert-select-pkcs11 gl/m4/fcntl-o.m4 gl/m4/fcntl_h.m4 gl/m4/pipe.m4 +doc/examples/ex-client-udp diff --git a/doc/cha-gtls-app.texi b/doc/cha-gtls-app.texi index 3f907e205c..e91b135430 100644 --- a/doc/cha-gtls-app.texi +++ b/doc/cha-gtls-app.texi @@ -175,6 +175,7 @@ implemented by another example. @menu * Simple client example with anonymous authentication:: * Simple client example with X.509 certificate support:: +* Simple Datagram TLS client example:: * Obtaining session information:: * Verifying peer's certificate:: * Using a callback to select the certificate to use:: @@ -210,6 +211,15 @@ redefining them. @verbatiminclude examples/ex-client2.c +@node Simple Datagram TLS client example +@subsection Simple Datagram @acronym{TLS} client example + +This is a client that uses @acronym{UDP} to connect to a +server. This is the @acronym{DTLS} equivalent to +@ref{Simple client example with X.509 certificate support} above. + +@verbatiminclude examples/ex-client-udp.c + @node Obtaining session information @subsection Obtaining Session Information diff --git a/doc/cha-intro-tls.texi b/doc/cha-intro-tls.texi index e2dd8a7c96..3439ceba6f 100644 --- a/doc/cha-intro-tls.texi +++ b/doc/cha-intro-tls.texi @@ -1,5 +1,5 @@ @node Introduction to TLS -@chapter Introduction to @acronym{TLS} +@chapter Introduction to @acronym{TLS} and @acronym{DTLS} @acronym{TLS} stands for ``Transport Layer Security'' and is the successor of SSL, the Secure Sockets Layer protocol @xcite{SSL3} @@ -12,11 +12,17 @@ It is open to any interested individual.}, described in @acronym{RFC} 4346 and also in @xcite{RESCORLA}. The protocol provides confidentiality, and authentication layers over any reliable transport layer. The description, below, refers to @acronym{TLS} 1.0 but also -applies to @acronym{TLS} 1.1 @xcite{RFC4346} and @acronym{SSL} 3.0, -since the differences of these protocols are minor. Older protocols -such as @acronym{SSL} 2.0 are not discussed nor implemented in -@acronym{GnuTLS} since they are not considered secure today. GnuTLS -also supports @acronym{X.509} and @acronym{OpenPGP} @xcite{RFC4880}. +applies to @acronym{TLS} 1.2 @xcite{RFC4346} and @acronym{SSL} 3.0, +since the differences of these protocols are not major. + +The @acronym{DTLS} protocol, or ``Datagram @acronym{TLS}'' is a +protocol with identical goals as @acronym{TLS}, but can operate +under unreliable transport layers, such as @acronym{UDP}. The +discussions below apply to this protocol as well, except when +noted otherwise. + +Older protocols such as @acronym{SSL} 2.0 are not discussed nor implemented in +@acronym{GnuTLS} since they are not considered secure today. @menu * TLS layers:: @@ -65,6 +71,7 @@ required callbacks to access the transport layer. @itemize @item @ref{gnutls_transport_set_push_function} @item @ref{gnutls_transport_set_vec_push_function} +@item @ref{gnutls_transport_set_pull_timeout_function} (for @acronym{DTLS} only) @item @ref{gnutls_transport_set_pull_function} @item @ref{gnutls_transport_set_ptr} @item @ref{gnutls_transport_set_errno} @@ -89,6 +96,12 @@ again), if any of these error codes is returned. The error codes above refer to the system call, not the @acronym{GnuTLS} function, since signals do not interrupt @acronym{GnuTLS}' functions. +@acronym{DTLS} however deviates from this rule. Because it requires +timers and waiting for peer's messages during the handshake process, +@acronym{GnuTLS} will block and might be interrupted by signals. The +blocking operation of @acronym{GnuTLS} during @acronym{DTLS} handshake +can be changed using the appropriate flags in @ref{gnutls_init}. + By default, if the transport functions are not set, @acronym{GnuTLS} will use the Berkeley Sockets functions. @@ -103,15 +116,30 @@ The following functions are available: @table @asis @item @ref{gnutls_record_send}: -To send a record packet (with application data). +To send a record packet with application data. @item @ref{gnutls_record_recv}: -To receive a record packet (with application data). +To receive a record packet with application data. + +@item @ref{gnutls_record_recv_seq}: +To receive a record packet with application data as well +as the sequence number of that. This is useful in @acronym{DTLS} +where packets might be lost or received out of order. @item @ref{gnutls_record_get_direction}: To get the direction of the last interrupted function call. @end table +In @acronym{TLS} those functions can be called at any time after +the handshake process is finished, when there is need to receive +or send data. In @acronym{DTLS} however, due to re-transmission +timers used in the handshake out-of-order handshake data might +be received for some time (maximum 60 seconds) after the handshake +process is finished. For this reason programs using @acronym{DTLS} +should call @ref{gnutls_record_recv} or @ref{gnutls_record_recv_seq} +for every packet received by the peer, even if no data were +expected. + As you may have already noticed, the functions which access the Record protocol, are quite limited, given the importance of this protocol in @acronym{TLS}. This is because the Record protocol's parameters are @@ -161,6 +189,10 @@ which is considered weak. @item AES_CBC AES or RIJNDAEL is the block cipher algorithm that replaces the old DES algorithm. Has 128 bits block size and is used in CBC mode. + +@item AES_GCM +This is the AES algorithm in the authenticated encryption GCM mode. +This mode combines message authentication and encryption. @end table Supported MAC algorithms: diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am index f7f61d89eb..bafa2a3491 100644 --- a/doc/examples/Makefile.am +++ b/doc/examples/Makefile.am @@ -40,7 +40,7 @@ LDADD = libexamples.la \ CXX_LDADD = $(LDADD) \ ../../lib/libgnutlsxx.la -noinst_PROGRAMS = ex-client2 ex-client-resume +noinst_PROGRAMS = ex-client2 ex-client-resume ex-client-udp noinst_PROGRAMS += ex-cert-select ex-rfc2818 noinst_PROGRAMS += ex-cert-select-pkcs11 @@ -77,4 +77,4 @@ noinst_LTLIBRARIES = libexamples.la libexamples_la_SOURCES = examples.h ex-alert.c ex-pkcs12.c \ ex-session-info.c ex-x509-info.c ex-verify.c \ - tcp.c + tcp.c udp.c diff --git a/doc/examples/ex-client-udp.c b/doc/examples/ex-client-udp.c new file mode 100644 index 0000000000..f49d3d28ca --- /dev/null +++ b/doc/examples/ex-client-udp.c @@ -0,0 +1,120 @@ +/* This example code is placed in the public domain. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <unistd.h> +#include <gnutls/gnutls.h> +#include <gnutls/dtls.h> + +/* A very basic Datagram TLS client, over UDP with X.509 authentication. + */ + +#define MAX_BUF 1024 +#define CAFILE "ca.pem" +#define MSG "GET / HTTP/1.0\r\n\r\n" + +extern int udp_connect (void); +extern void udp_close (int sd); + +int +main (void) +{ + int ret, sd, ii; + gnutls_session_t session; + char buffer[MAX_BUF + 1]; + const char *err; + gnutls_certificate_credentials_t xcred; + + gnutls_global_init (); + + /* X509 stuff */ + gnutls_certificate_allocate_credentials (&xcred); + + /* sets the trusted cas file */ + gnutls_certificate_set_x509_trust_file (xcred, CAFILE, GNUTLS_X509_FMT_PEM); + + /* Initialize TLS session */ + gnutls_init (&session, GNUTLS_CLIENT|GNUTLS_DATAGRAM); + + /* Use default priorities */ + ret = gnutls_priority_set_direct (session, "NORMAL", &err); + if (ret < 0) + { + if (ret == GNUTLS_E_INVALID_REQUEST) + { + fprintf (stderr, "Syntax error at: %s\n", err); + } + exit (1); + } + + /* put the x509 credentials to the current session */ + gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + + /* connect to the peer */ + sd = udp_connect (); + + gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd); + + /* set the connection MTU */ + gnutls_dtls_set_mtu (session, 1000); + + /* Perform the TLS handshake */ + ret = gnutls_handshake (session); + + if (ret < 0) + { + fprintf (stderr, "*** Handshake failed\n"); + gnutls_perror (ret); + goto end; + } + else + { + printf ("- Handshake was completed\n"); + } + + gnutls_record_send (session, MSG, strlen (MSG)); + + ret = gnutls_record_recv (session, buffer, MAX_BUF); + if (ret == 0) + { + printf ("- Peer has closed the TLS connection\n"); + goto end; + } + else if (ret < 0) + { + fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret)); + goto end; + } + + printf ("- Received %d bytes: ", ret); + for (ii = 0; ii < ret; ii++) + { + fputc (buffer[ii], stdout); + } + fputs ("\n", stdout); + + /* It is suggested not to use GNUTLS_SHUT_RDWR in DTLS + * connections because the peer's closure message might + * be lost */ + gnutls_bye (session, GNUTLS_SHUT_WR); + +end: + + udp_close (sd); + + gnutls_deinit (session); + + gnutls_certificate_free_credentials (xcred); + + gnutls_global_deinit (); + + return 0; +} diff --git a/doc/examples/udp.c b/doc/examples/udp.c new file mode 100644 index 0000000000..3eb567af50 --- /dev/null +++ b/doc/examples/udp.c @@ -0,0 +1,58 @@ +/* This example code is placed in the public domain. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <unistd.h> + +#define SA struct sockaddr + +/* tcp.c */ +int udp_connect (void); +void udp_close (int sd); + +/* Connects to the peer and returns a socket + * descriptor. + */ +extern int +udp_connect (void) +{ + const char *PORT = "5557"; + const char *SERVER = "127.0.0.1"; + int err, sd; + struct sockaddr_in sa; + + /* connects to server + */ + sd = socket (AF_INET, SOCK_DGRAM, 0); + + memset (&sa, '\0', sizeof (sa)); + sa.sin_family = AF_INET; + sa.sin_port = htons (atoi (PORT)); + inet_pton (AF_INET, SERVER, &sa.sin_addr); + + err = connect (sd, (SA *) & sa, sizeof (sa)); + if (err < 0) + { + fprintf (stderr, "Connect error\n"); + exit (1); + } + + return sd; +} + +/* closes the given socket descriptor. + */ +extern void +udp_close (int sd) +{ + close (sd); +} diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index f14927db18..ed3037db5c 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -282,8 +282,10 @@ _gnutls_handshake_internal_state_clear (gnutls_session_t session) * be allocated. This function allocates structures which can only * be free'd by calling gnutls_deinit(). Returns zero on success. * - * @flags can be one of %GNUTLS_CLIENT and %GNUTLS_SERVER and might - * include %GNUTLS_DATAGRAM to enable datagram TLS (DTLS). + * @flags can be one of %GNUTLS_CLIENT and %GNUTLS_SERVER. For a DTLS + * entity, the flags %GNUTLS_DATAGRAM and %GNUTLS_NONBLOCK are + * also available. The latter flag will enable a non-blocking + * operation of the DTLS timers. * * Returns: %GNUTLS_E_SUCCESS on success, or an error code. **/ |