gnutls-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gnutls branch, master, updated. gnutls_3_0_9-22-g76f2856


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_3_0_9-22-g76f2856
Date: Wed, 28 Dec 2011 14:45:03 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gnutls".

http://git.savannah.gnu.org/cgit/gnutls.git/commit/?id=76f2856a51f4cae238aa3117e03ac7a8204dff9f

The branch, master has been updated
       via  76f2856a51f4cae238aa3117e03ac7a8204dff9f (commit)
       via  78bf1de9b111485037388893bf2ccc766f8d167d (commit)
       via  8d4c4cafee906ea8e5f27de6a1c8d1cb45117eda (commit)
       via  87ed97f3046dcc7f80d4ae70b40045f3a82112ed (commit)
       via  c279f32d5ffc41ab41a1441687dcb9daea5e6475 (commit)
       via  725cf45965e66b8d5a19fa39b679d0a2c505ce0f (commit)
       via  d2ff834b0b7224f808eea3e2f3cda0b8d0f17a08 (commit)
       via  89ee549eb59e2d627548bb79e2ccfa589791d98c (commit)
       via  ed1a8c31f04de6313533db28b3154efdd4338533 (commit)
       via  7e4d424ef99f39a2a6d5fd13146281d9744d3c0b (commit)
       via  e38f4775671c15170638c865d2edf3025930ef76 (commit)
       via  7f2a529e3dfad850e2cbd599ab3c4a4febbea05c (commit)
       via  79af6bb434d646b6a05f19b699c68ceba11fb704 (commit)
      from  e943839de12ca459e298136af445f697de07d300 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 76f2856a51f4cae238aa3117e03ac7a8204dff9f
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Dec 28 16:24:18 2011 +0200

    gnutls_atfork was no longer in use.

commit 78bf1de9b111485037388893bf2ccc766f8d167d
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Dec 28 16:12:17 2011 +0200

    Added function gnutls_random_art() to convert fingerprints to images 
(currently ascii-art).

commit 8d4c4cafee906ea8e5f27de6a1c8d1cb45117eda
Author: Patrick Pelletier <address@hidden>
Date:   Wed Dec 28 01:37:06 2011 -0800

    minor doc and comment fixes
    
    Signed-off-by: Nikos Mavrogiannopoulos <address@hidden>

commit 87ed97f3046dcc7f80d4ae70b40045f3a82112ed
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Dec 28 10:49:56 2011 +0200

    updated examples and added new "handling alerts" section.

commit c279f32d5ffc41ab41a1441687dcb9daea5e6475
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Dec 28 10:40:32 2011 +0200

    updated and included in the documentation the udp code.

commit 725cf45965e66b8d5a19fa39b679d0a2c505ce0f
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Dec 28 10:32:48 2011 +0200

    Set don't fragment bit in Linux as well as in BSD variants.

commit d2ff834b0b7224f808eea3e2f3cda0b8d0f17a08
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Tue Dec 27 23:32:12 2011 +0200

    updated server examples

commit 89ee549eb59e2d627548bb79e2ccfa589791d98c
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Dec 26 17:12:49 2011 +0200

    smallexample is no longer used. It is intended only for typesetting with 
smaller pages and had no relation to our usage.

commit ed1a8c31f04de6313533db28b3154efdd4338533
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Dec 26 17:08:56 2011 +0200

    prepend UDP to server application name when in UDP mode.

commit 7e4d424ef99f39a2a6d5fd13146281d9744d3c0b
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Dec 26 17:08:20 2011 +0200

    Added DTLS server example.

commit e38f4775671c15170638c865d2edf3025930ef76
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Dec 26 17:07:47 2011 +0200

    corrected a leak

commit 7f2a529e3dfad850e2cbd599ab3c4a4febbea05c
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Dec 26 15:32:41 2011 +0200

    Added SECP192R1 curve.

commit 79af6bb434d646b6a05f19b699c68ceba11fb704
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Dec 26 15:31:08 2011 +0200

    pkcs11.h and abstract.h use extern C idiom for C++.

-----------------------------------------------------------------------

Summary of changes:
 .gitignore                                         |    1 +
 NEWS                                               |    8 +-
 configure.ac                                       |    1 +
 doc/Makefile.am                                    |    8 +-
 doc/cha-cert-auth.texi                             |    4 +-
 doc/cha-cert-auth2.texi                            |   88 ++--
 doc/cha-gtls-app.texi                              |   55 ++-
 doc/cha-gtls-examples.texi                         |   73 +++--
 doc/cha-internals.texi                             |    2 +-
 doc/cha-intro-tls.texi                             |   10 +-
 doc/cha-programs.texi                              |   52 ++--
 doc/cha-shared-key.texi                            |   20 +-
 doc/examples/Makefile.am                           |    8 +-
 doc/examples/{ex-client1.c => ex-client-anon.c}    |    6 +-
 doc/examples/{ex-client-udp.c => ex-client-dtls.c} |    8 +-
 doc/examples/ex-client-psk.c                       |    6 +-
 doc/examples/ex-client-resume.c                    |    6 +-
 doc/examples/ex-client-srp.c                       |    6 +-
 doc/examples/{ex-rfc2818.c => ex-client-x509.c}    |    2 +
 doc/examples/ex-serv-anon.c                        |    8 +-
 doc/examples/ex-serv-dtls.c                        |  432 ++++++++++++++++++++
 doc/examples/ex-serv-srp.c                         |    8 +-
 doc/examples/{ex-serv1.c => ex-serv-x509.c}        |   51 ++--
 doc/examples/udp.c                                 |   18 +-
 lib/Makefile.am                                    |    3 +-
 lib/algorithms/ciphers.c                           |    4 +-
 lib/algorithms/protocols.c                         |    2 +-
 lib/algorithms/secparams.c                         |    2 +-
 lib/{openpgp => extras}/Makefile.am                |    7 +-
 lib/extras/randomart.c                             |  147 +++++++
 lib/extras/randomart.h                             |    3 +
 lib/gnutls_cert.c                                  |    2 +-
 lib/gnutls_cipher.c                                |    2 +-
 lib/gnutls_db.c                                    |    8 +-
 lib/gnutls_global.c                                |    4 +-
 lib/gnutls_handshake.c                             |    2 +-
 lib/gnutls_priority.c                              |    4 +-
 lib/gnutls_state.c                                 |    4 +-
 lib/gnutls_ui.c                                    |   40 ++-
 lib/includes/gnutls/abstract.h                     |    9 +
 lib/includes/gnutls/gnutls.h.in                    |   12 +-
 lib/includes/gnutls/pkcs11.h                       |    9 +
 lib/libgnutls.map                                  |    1 +
 lib/nettle/rnd.c                                   |    6 +-
 lib/openpgp/output.c                               |   23 +
 lib/system.c                                       |   22 -
 lib/system.h                                       |    2 -
 lib/x509/output.c                                  |   25 +-
 src/cli.c                                          |   15 +-
 src/serv.c                                         |   21 +-
 src/udp-serv.c                                     |    1 +
 51 files changed, 1008 insertions(+), 253 deletions(-)
 rename doc/examples/{ex-client1.c => ex-client-anon.c} (95%)
 rename doc/examples/{ex-client-udp.c => ex-client-dtls.c} (92%)
 rename doc/examples/{ex-rfc2818.c => ex-client-x509.c} (97%)
 create mode 100644 doc/examples/ex-serv-dtls.c
 rename doc/examples/{ex-serv1.c => ex-serv-x509.c} (80%)
 copy lib/{openpgp => extras}/Makefile.am (85%)
 create mode 100644 lib/extras/randomart.c
 create mode 100644 lib/extras/randomart.h

diff --git a/.gitignore b/.gitignore
index 7e45f14..f06f9f3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -70,6 +70,7 @@ doc/examples/ex-serv-pgp
 doc/examples/ex-serv-psk
 doc/examples/ex-serv-srp
 doc/examples/ex-serv1
+doc/examples/ex-serv-dtls
 doc/examples/libexamples.la
 doc/extra.c.texi
 doc/gnutls-api.texi
diff --git a/NEWS b/NEWS
index 499281b..be88c61 100644
--- a/NEWS
+++ b/NEWS
@@ -4,13 +4,19 @@ See the end for copying conditions.
 
 * Version 3.0.10 (unreleased)
 
+** gnutls-cli/serv: Set don't fragment bit in DTLS sessions
+in Linux as well as in BSD.
+
 ** libgnutls: Corrected ciphersuite GNUTLS_ECDHE_PSK_AES_256_CBC_SHA384
 
 ** libgnutls: Added ciphersuites: GNUTLS_PSK_WITH_AES_256_GCM_SHA384
 and GNUTLS_DHE_PSK_WITH_AES_256_GCM_SHA384.
 
+** libgnutls: Added function gnutls_random_art() to convert 
+fingerprints to images (currently ascii-art).
+
 ** API and ABI modifications:
-No changes since last version.
+gnutls_random_art: Added
 
 
 * Version 3.0.9 (released 2011-12-13)
diff --git a/configure.ac b/configure.ac
index 2d3a359..ebc8625 100644
--- a/configure.ac
+++ b/configure.ac
@@ -465,6 +465,7 @@ AC_CONFIG_FILES([
   lib/algorithms/Makefile
   lib/auth/Makefile
   lib/ext/Makefile
+  lib/extras/Makefile
   lib/gnutls.pc
   lib/includes/Makefile
   lib/includes/gnutls/gnutls.h
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 41619a8..d391260 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -39,14 +39,14 @@ gnutls_TEXINFOS = gnutls.texi fdl-1.3.texi lgpl-2.1.texi 
gpl-3.0.texi       \
        cha-shared-key.texi cha-gtls-examples.texi
 
 # Examples.
-gnutls_TEXINFOS += examples/ex-client1.c                               \
+gnutls_TEXINFOS += examples/ex-client-anon.c                           \
        examples/ex-session-info.c examples/ex-verify.c                 \
        examples/ex-cert-select.c examples/ex-client-resume.c           \
-       examples/ex-client-srp.c examples/ex-rfc2818.c                  \
-       examples/ex-serv1.c examples/ex-serv-anon.c                     \
+       examples/ex-client-srp.c examples/ex-client-x509.c              \
+       examples/ex-serv-x509.c examples/ex-serv-anon.c                 \
        examples/ex-serv-pgp.c examples/ex-serv-srp.c                   \
        examples/ex-alert.c examples/ex-x509-info.c examples/ex-crq.c   \
-       examples/ex-pkcs12.c
+       examples/ex-pkcs12.c examples/ex-client-dtls.c
 
 # Images.  Make sure there are eps + png + pdf of each, plus the source dia.
 gnutls_TEXINFOS += gnutls-internals.dia gnutls-internals.eps           \
diff --git a/doc/cha-cert-auth.texi b/doc/cha-cert-auth.texi
index df9d388..924b2b3 100644
--- a/doc/cha-cert-auth.texi
+++ b/doc/cha-cert-auth.texi
@@ -372,10 +372,10 @@ certificate chain, you can call
 @end itemize
 as in the following example:
 
address@hidden
address@hidden
   gnutls_certificate_set_verify_flags (x509cred,
                                        GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
address@hidden smallexample
address@hidden example
 
 This will tell the verifier algorithm to enable @code{RSA-MD5} when
 verifying the certificates.
diff --git a/doc/cha-cert-auth2.texi b/doc/cha-cert-auth2.texi
index 61fe854..b4f2fd0 100644
--- a/doc/cha-cert-auth2.texi
+++ b/doc/cha-cert-auth2.texi
@@ -281,18 +281,18 @@ example of a template file.
 
 @subheading Diffie-Hellman parameter generation
 To generate parameters for Diffie-Hellman key exchange, use the command:
address@hidden
address@hidden
 $ certtool --generate-dh-params --outfile dh.pem
address@hidden smallexample
address@hidden example
 
 @subheading Self-signed certificate generation
 
 To create a self signed certificate, use the command:
address@hidden
address@hidden
 $ certtool --generate-privkey --outfile ca-key.pem
 $ certtool --generate-self-signed --load-privkey ca-key.pem \
    --outfile ca-cert.pem
address@hidden smallexample
address@hidden example
 
 Note that a self-signed certificate usually belongs to a certificate
 authority, that signs other certificates.
@@ -300,9 +300,9 @@ authority, that signs other certificates.
 @subheading Private key generation
 To create a private key (RSA by default), run:
 
address@hidden
address@hidden
 $ certtool --generate-privkey --outfile key.pem
address@hidden smallexample
address@hidden example
 
 To create a DSA or elliptic curves (ECDSA) private key use the
 above command combined with @code{--dsa} or @code{--ecc} options.
@@ -310,63 +310,63 @@ above command combined with @code{--dsa} or @code{--ecc} 
options.
 @subheading Certificate generation
 To generate a certificate using the private key, use the command:
 
address@hidden
address@hidden
 $ certtool --generate-certificate --load-privkey key.pem \
    --outfile cert.pem --load-ca-certificate ca-cert.pem \
    --load-ca-privkey ca-key.pem
address@hidden smallexample
address@hidden example
 
 Alternatively you may create a certificate request, which is needed
 when the certificate will be signed by a third party authority.
 
address@hidden
address@hidden
 $ certtool --generate-request --load-privkey key.pem \
   --outfile request.pem
address@hidden smallexample
address@hidden example
 
 If the private key is stored in a smart card you can generate
 a request by specifying the private key object URL (see @ref{The p11tool 
application}
 on how to obtain the URL).
 
address@hidden
address@hidden
 $ certtool --generate-request --load-privkey pkcs11:(PRIVKEY URL) \
   --load-pubkey pkcs11:(PUBKEY URL) --outfile request.pem
address@hidden smallexample
address@hidden example
 
 To generate a certificate using the previous request, use the command:
 
address@hidden
address@hidden
 $ certtool --generate-certificate --load-request request.pem \
    --outfile cert.pem \
    --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem
address@hidden smallexample
address@hidden example
 
 @subheading Certificate information
 To view the certificate information, use:
 
address@hidden
address@hidden
 $ certtool --certificate-info --infile cert.pem
address@hidden smallexample
address@hidden example
 
 @subheading @acronym{PKCS} #12 structure generation
 To generate a @acronym{PKCS} #12 structure using the previous key and
 certificate, use the command:
 
address@hidden
address@hidden
 $ certtool --load-certificate cert.pem --load-privkey key.pem \
   --to-p12 --outder --outfile key.p12
address@hidden smallexample
address@hidden example
 
 Some tools (reportedly web browsers) have problems with that file
 because it does not contain the CA certificate for the certificate.
 To work around that problem in the tool, you can use the
 --load-ca-certificate parameter as follows:
 
address@hidden
address@hidden
 $ certtool --load-ca-certificate ca.pem \
   --load-certificate cert.pem --load-privkey key.pem \
   --to-p12 --outder --outfile key.p12
address@hidden smallexample
address@hidden example
 
 @subheading Proxy certificate generation
 Proxy certificate can be used to delegate your credential to a
@@ -374,34 +374,34 @@ temporary, typically short-lived, certificate.  To create 
one from the
 previously created certificate, first create a temporary key and then
 generate a proxy certificate for it, using the commands:
 
address@hidden
address@hidden
 $ certtool --generate-privkey > proxy-key.pem
 $ certtool --generate-proxy --load-ca-privkey key.pem \
   --load-privkey proxy-key.pem --load-certificate cert.pem \
   --outfile proxy-cert.pem
address@hidden smallexample
address@hidden example
 
 @subheading Certificate revocation list generation
 To create an empty Certificate Revocation List (CRL) do:
 
address@hidden
address@hidden
 $ certtool --generate-crl --load-ca-privkey x509-ca-key.pem \
            --load-ca-certificate x509-ca.pem
address@hidden smallexample
address@hidden example
 
 To create a CRL that contains some revoked certificates, place the
 certificates in a file and use @code{--load-certificate} as follows:
 
address@hidden
address@hidden
 $ certtool --generate-crl --load-ca-privkey x509-ca-key.pem \
   --load-ca-certificate x509-ca.pem --load-certificate revoked-certs.pem
address@hidden smallexample
address@hidden example
 
 To verify a Certificate Revocation List (CRL) do:
 
address@hidden
address@hidden
 $ certtool --verify-crl --load-ca-certificate x509-ca.pem < crl.pem
address@hidden smallexample
address@hidden example
 
 
 
@@ -410,11 +410,11 @@ A template file can be used to avoid the interactive 
questions of
 certtool. Initially create a file named 'cert.cfg' that contains the 
information
 about the certificate. The template can be used as below:
 
address@hidden
address@hidden
 $ certtool --generate-certificate cert.pem --load-privkey key.pem  \
    --template cert.cfg \
    --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem
address@hidden smallexample
address@hidden example
 
 An example certtool template file:
 
@@ -571,9 +571,9 @@ These are the configuration files of 
@address@hidden@url{http://p11-
 For example a file that will load the @acronym{OpenSC} module, could be named
 @code{/etc/pkcs11/modules/opensc} and contain the following:
 
address@hidden
address@hidden
 module: /usr/lib/opensc-pkcs11.so
address@hidden smallexample
address@hidden example
 
 If you use this file, then there is no need for other initialization in
 @acronym{GnuTLS}, except for the PIN and token functions. Those allow 
retrieving a PIN
@@ -597,16 +597,16 @@ This allows for a consistent naming of objects across 
systems and applications
 in the same system. For example a public
 key on a smart card may be referenced as:
 
address@hidden
address@hidden
 pkcs11:token=Nikos;serial=307521161601031;model=PKCS%2315; \
 manufacturer=EnterSafe;object=test1;objecttype=public;\
 id=32f153f3e37990b08624141077ca5dec2d15faed
address@hidden smallexample
address@hidden example
 
 while the smart card itself can be referenced as:
address@hidden
address@hidden
 
pkcs11:token=Nikos;serial=307521161601031;model=PKCS%2315;manufacturer=EnterSafe
address@hidden smallexample
address@hidden example
 
 Objects stored in a @acronym{PKCS} #11 token can be extracted
 if they are not marked as sensitive. Usually only private keys are marked as
@@ -747,32 +747,32 @@ on them.
 Some examples on how to use p11tool are illustrated in the following  
paragraphs.
 
 @subsubheading List all tokens
address@hidden
address@hidden
 $ p11tool --list-tokens
address@hidden smallexample
address@hidden example
 
 @subsubheading List all objects
 The following command will list all objects in a token. The @code{--login}
 is required to show objects marked as private.
address@hidden
address@hidden
 $ p11tool --login --list-all
address@hidden smallexample
address@hidden example
 
 @subsubheading Exporting an object
 To retrieve an object stored in the card use the following command.
 Note however that objects marked as sensitive (typically PKCS #11 private 
keys) 
 are not allowed to be extracted from the token.
address@hidden 
address@hidden 
 $ p11tool --login --export [OBJECT URL]
address@hidden smallexample
address@hidden example
 
 @subsubheading Copy an object to a token
 To copy an object, such as a certificate or private key to a token
 use the following command.
address@hidden 
address@hidden 
 $ p11tool --login --write [TOKEN URL] \
   --load-certificate cert.pem --label "my_cert"
address@hidden smallexample
address@hidden example
 
 
 @node Abstract key types
diff --git a/doc/cha-gtls-app.texi b/doc/cha-gtls-app.texi
index 32c806e..3bd9866 100644
--- a/doc/cha-gtls-app.texi
+++ b/doc/cha-gtls-app.texi
@@ -9,6 +9,7 @@
 * Setting up the transport layer::
 * TLS handshake::
 * Data transfer and termination::
+* Handling alerts::
 * Priority Strings::
 * Advanced and other topics::
 * Using the cryptographic library::
@@ -130,10 +131,10 @@ The random generator of the cryptographic back-end, is 
not thread safe and requi
 mutex locks which are setup by @acronym{GnuTLS}.
 Applications can either call @funcref{gnutls_global_init} which will 
initialize the default
 operating system provided locks (i.e. @code{pthreads} on GNU/Linux and
address@hidden on Windows), or specify manually the locking system using 
address@hidden on Windows), or manually specify the locking system using
 the function @funcref{gnutls_global_set_mutex} before calling 
@funcref{gnutls_global_init}. 
-Setting manually mutexes is recommended
-only to applications that have full control of the underlying libraries. If 
this
+Setting mutexes manually is recommended
+only for applications that have full control of the underlying libraries. If 
this
 is not the case, the use of the operating system defaults is recommended. An 
example of 
 non-native thread usage is shown below.
 
@@ -237,9 +238,9 @@ to be added to the compiler invocation at compile time are 
output by
 the @option{--cflags} option to @command{pkg-config gnutls}.  The
 following example shows how it can be used at the command line:
 
address@hidden
address@hidden
 gcc -c foo.c `pkg-config gnutls --cflags`
address@hidden smallexample
address@hidden example
 
 Adding the output of @samp{pkg-config gnutls --cflags} to the
 compilers command line will ensure that the compiler can find the
@@ -255,16 +256,16 @@ required to link the program with the library (for 
instance, the
 @samp{-ltasn1} option).  The example shows how to link @file{foo.o}
 with the library to a program @command{foo}.
 
address@hidden
address@hidden
 gcc -o foo foo.o `pkg-config gnutls --libs`
address@hidden smallexample
address@hidden example
 
 Of course you can also combine both examples to a single command by
 specifying both options to @command{pkg-config}:
 
address@hidden
address@hidden
 gcc -o foo foo.c `pkg-config gnutls --cflags --libs`
address@hidden smallexample
address@hidden example
 
 @node Session initialization
 @section Session initialization
@@ -305,7 +306,7 @@ current session using @funcref{gnutls_credentials_set}.
 
 When using certificates the server is required to have at least one
 certificate and private key pair. Clients may not hold such
-a pair, but a server could require it. On this section we discuss
+a pair, but a server could require it. In this section we discuss
 general issues applying to both client and server certificates. The next
 section will elaborate on issues arising from client authentication only.
 
@@ -617,7 +618,7 @@ fatal for the protocol or can be ignored.
 
 @showfuncdesc{gnutls_error_is_fatal}
 
-In DTLS it is adviceable to use the extended receive
+In DTLS it is advisable to use the extended receive
 function shown below, because it allows the extraction
 of the sequence number. This is required in DTLS because
 messages may arrive out of order.
@@ -643,6 +644,24 @@ A session can be deinitialized with the 
@funcref{gnutls_deinit} function.
 @showfuncdesc{gnutls_bye}
 @showfuncdesc{gnutls_deinit}
 
address@hidden Handling alerts
address@hidden Handling alerts
+During a TLS connection alert messages may be exchanged by the
+two peers. Those messages may be fatal, meaning the connection
+must be terminated afterwards, or warning when something needs
+to be reported to the peer, but without interrupting the session.
+The error codes @code{GNUTLS_E_WARNING_ALERT_RECEIVED}
+or @code{GNUTLS_E_FATAL_ALERT_RECEIVED} signal those alerts
+when received, and may be returned by all GnuTLS functions that receive 
+data from the peer, being @funcref{gnutls_handshake} and 
@funcref{gnutls_record_recv}.
+Alerts messages may be sent to the peer using @funcref{gnutls_alert_send}.
+
address@hidden
+
address@hidden
+
address@hidden,gnutls_alert_get_name}
+
 
 @node Priority Strings
 @section Priority strings
@@ -750,7 +769,7 @@ COMP-NULL, COMP-DEFLATE. Catch all is COMP-ALL.
 
 @item TLS versions @tab
 VERS-SSL3.0, VERS-TLS1.0, VERS-TLS1.1,
-VERS-TLS1.2. Catch all is VERS-TLS-ALL.
+VERS-TLS1.2, VERS-DTLS1.0. Catch all is VERS-TLS-ALL.
 
 @item Signature algorithms @tab
 SIGN-RSA-SHA1, SIGN-RSA-SHA224, 
@@ -759,7 +778,7 @@ SIGN-DSA-SHA224, SIGN-DSA-SHA256, SIGN-RSA-MD5. Catch all
 is SIGN-ALL. This is only valid for TLS 1.2 and later.
 
 @item Elliptic curves @tab
-CURVE-SECP224R1, CURVE-SECP256R1, CURVE-SECP384R1, CURVE-SECP521R1. Catch all 
is CURVE-ALL.
+CURVE-SECP192R1, CURVE-SECP224R1, CURVE-SECP256R1, CURVE-SECP384R1, 
CURVE-SECP521R1. Catch all is CURVE-ALL.
 
 @end multitable
 @caption{The supported algorithm keywords in priority strings.}
@@ -861,7 +880,7 @@ even it was requested.  That is to prevent temporal session 
keys
 from becoming long-term keys. Also note that as a client you must enable, 
using the
 priority functions, at least the algorithms used in the last session.
 
-It is highly recommended clients to enable the session ticket extension using 
+It is highly recommended for clients to enable the session ticket extension 
using
 @funcref{gnutls_session_ticket_enable_client} in order to allow resumption 
with 
 servers that do not store any state.
 
@@ -948,13 +967,13 @@ client or server random data first, you can set the
 For example, after establishing a TLS session using
 @funcref{gnutls_handshake}, you can invoke the TLS PRF with this call:
 
address@hidden
address@hidden
 #define MYLABEL "EXPORTER-FOO"
 #define MYCONTEXT "some context data"
 char out[32];
 rc = gnutls_prf (session, strlen (MYLABEL), MYLABEL, 0,
                  strlen (MYCONTEXT), MYCONTEXT, 32, out);
address@hidden smallexample
address@hidden example
 
 If you don't want to mix in the client/server random, there is a more
 low-level TLS PRF interface called @funcref{gnutls_prf_raw}.
@@ -979,7 +998,7 @@ the @code{tls-unique} channel binding for TLS defined in
 The following example describes how to print the channel binding data.
 Note that it must be run after a successful TLS handshake.
 
address@hidden
address@hidden
 @{
   gnutls_datum_t cb;
   int rc;
@@ -999,7 +1018,7 @@ Note that it must be run after a successful TLS handshake.
       printf ("\n");
     @}
 @}
address@hidden smallexample
address@hidden example
 
 @node Interoperability
 @subsection Interoperability
diff --git a/doc/cha-gtls-examples.texi b/doc/cha-gtls-examples.texi
index 7ce4ee1..fed30d5 100644
--- a/doc/cha-gtls-examples.texi
+++ b/doc/cha-gtls-examples.texi
@@ -25,11 +25,12 @@ implemented by another example.
 * Obtaining session information::
 * Using a callback to select the certificate to use::
 * Verifying a certificate::
-* Client using a PKCS 11 token with TLS::
+* Client using a smart card with TLS::
 * Client with Resume capability example::
 * Simple client example with SRP authentication::
 * Simple client example in C++::
-* Helper function for TCP connections::
+* Helper functions for TCP connections::
+* Helper functions for UDP connections::
 @end menu
 
 @node Simple client example with anonymous authentication
@@ -39,9 +40,10 @@ The simplest client using TLS is the one that doesn't do any
 authentication.  This means no external certificates or passwords are
 needed to set up the connection.  As could be expected, the connection
 is vulnerable to man-in-the-middle (active or redirection) attacks.
-However, the data is integrity and privacy protected.
+However, the data are integrity protected and encrypted from
+passive eavesdroppers.
 
address@hidden examples/ex-client1.c
address@hidden examples/ex-client-anon.c
 
 @node Simple client example with X.509 certificate support
 @subsection Simple client example with @acronym{X.509} certificate support
@@ -54,16 +56,16 @@ a very simple @acronym{TLS} client, which uses the high 
level verification
 functions for certificates, but does not support session
 resumption. 
 
address@hidden examples/ex-rfc2818.c
address@hidden examples/ex-client-x509.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 the example
-in @ref{Simple client example with X.509 certificate support}.
+server. This is the @acronym{DTLS} equivalent to the TLS example
+with X.509 certificates.
 
address@hidden examples/ex-client-udp.c
address@hidden examples/ex-client-dtls.c
 
 @node Obtaining session information
 @subsection Obtaining session information
@@ -95,12 +97,14 @@ functions to verify a given certificate list.
 
 @verbatiminclude examples/ex-verify.c
 
address@hidden Client using a PKCS 11 token with TLS
address@hidden Using a @acronym{PKCS} #11 token with TLS
address@hidden Client using a smart card with TLS
address@hidden Using a smart card with TLS
 @anchor{ex:pkcs11-client}
address@hidden Smart card example
 
 This example will demonstrate how to load keys and certificates
-from a @acronym{PKCS} #11 token, and use it with a TLS connection.
+from a smart-card or any other @acronym{PKCS} #11 token, and 
+use it in a TLS connection.
 
 @verbatiminclude examples/ex-cert-select-pkcs11.c
 
@@ -135,14 +139,22 @@ the GnuTLS C++ API.
 
 @verbatiminclude examples/ex-cxx.cpp
 
address@hidden Helper function for TCP connections
address@hidden Helper function for TCP connections
address@hidden Helper functions for TCP connections
address@hidden Helper functions for TCP connections
 
-This helper function abstracts away TCP connection handling from the
+Those helper function abstract away TCP connection handling from the
 other examples.  It is required to build some examples.
 
 @verbatiminclude examples/tcp.c
 
address@hidden Helper functions for UDP connections
address@hidden Helper functions for UDP connections
+
+The UDP helper functions abstract away UDP connection handling from the
+other examples.  It is required to build the examples using UDP.
+
address@hidden examples/udp.c
+
 @node Server examples
 @section Server examples
 
@@ -150,21 +162,22 @@ This section contains examples of @acronym{TLS} and 
@acronym{SSL}
 servers, using @acronym{GnuTLS}.
 
 @menu
-* Echo Server with X.509 authentication::
-* Echo Server with OpenPGP authentication::
-* Echo Server with SRP authentication::
-* Echo Server with anonymous authentication::
+* Echo server with X.509 authentication::
+* Echo server with OpenPGP authentication::
+* Echo server with SRP authentication::
+* Echo server with anonymous authentication::
+* DTLS echo server with X.509 authentication::
 @end menu
 
address@hidden Echo Server with X.509 authentication
address@hidden Echo server with X.509 authentication
 @subsection Echo server with @acronym{X.509} authentication
 
 This example is a very simple echo server which supports
address@hidden authentication, using the RSA ciphersuites.
address@hidden authentication.
 
address@hidden examples/ex-serv1.c
address@hidden examples/ex-serv-x509.c
 
address@hidden Echo Server with OpenPGP authentication
address@hidden Echo server with OpenPGP authentication
 @subsection Echo server with @acronym{OpenPGP} authentication
 @cindex OpenPGP server
 
@@ -176,7 +189,7 @@ them to keep these examples as simple as possible.
 
 @verbatiminclude examples/ex-serv-pgp.c
 
address@hidden Echo Server with SRP authentication
address@hidden Echo server with SRP authentication
 @subsection Echo server with @acronym{SRP} authentication
 
 This is a server which supports @acronym{SRP} authentication. It is
@@ -185,14 +198,22 @@ server. Here it is separate for simplicity.
 
 @verbatiminclude examples/ex-serv-srp.c
 
address@hidden Echo Server with anonymous authentication
address@hidden Echo Server with anonymous authentication
address@hidden Echo server with anonymous authentication
address@hidden Echo server with anonymous authentication
 
-This example server support anonymous authentication, and could be
+This example server supports anonymous authentication, and could be
 used to serve the example client for anonymous authentication.
 
 @verbatiminclude examples/ex-serv-anon.c
 
address@hidden DTLS echo server with X.509 authentication
address@hidden DTLS echo server with @acronym{X.509} authentication
+
+This example is a very simple echo server using Datagram TLS and 
address@hidden authentication.
+
address@hidden examples/ex-serv-dtls.c
+
 @node Miscellaneous examples
 @section Miscellaneous examples
 
diff --git a/doc/cha-internals.texi b/doc/cha-internals.texi
index 81eb8e6..d7ec167 100644
--- a/doc/cha-internals.texi
+++ b/doc/cha-internals.texi
@@ -250,7 +250,7 @@ parsing incoming extension data (both in the client and 
server).
 The @funcintref{_foobar_send_params} function is responsible for
 sending extension data (both in the client and server).
 
-If you receive length fields that doesn't match, return
+If you receive length fields that don't match, return
 @address@hidden@address@hidden  If you receive invalid
 data, return @address@hidden@address@hidden  You can use
 other error codes from the list in @ref{Error codes}.  Return 0 on success.
diff --git a/doc/cha-intro-tls.texi b/doc/cha-intro-tls.texi
index 5f5f77d..6b1bb72 100644
--- a/doc/cha-intro-tls.texi
+++ b/doc/cha-intro-tls.texi
@@ -271,18 +271,10 @@ warning. Fatal alerts always terminate the current 
connection, and
 prevent future re-negotiations using the current session ID. All alert
 messages are summarized in @ref{tab:alerts}.
 
-
 The alert messages are protected by the record protocol, thus the
 information that is included does not leak. You must take extreme care
 for the alert information not to leak to a possible attacker, via
-public log files etc. The available functions to control the alert
-protocol are shown below.
-
address@hidden
-
address@hidden
-
address@hidden,gnutls_alert_get_name}
+public log files etc. 
 
 @include alerts.texi
 
diff --git a/doc/cha-programs.texi b/doc/cha-programs.texi
index 2327e85..42cb4a9 100644
--- a/doc/cha-programs.texi
+++ b/doc/cha-programs.texi
@@ -85,7 +85,7 @@ To connect to a server using PSK authentication, you need to 
enable
 the choice of PSK by using a cipher priority parameter such as in the
 example below.
 
address@hidden
address@hidden
 $ ./gnutls-cli -p 5556 localhost --pskusername psk_identity \
   --pskkey 88f3824b3e5659f52d00e959bacab954b6540344 \
   --priority NORMAL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK
@@ -100,7 +100,7 @@ Connecting to '127.0.0.1:5556'...
 - Handshake was completed
 
 - Simple Client Mode:
address@hidden smallexample
address@hidden example
 
 By keeping the @code{--pskusername} parameter and removing the
 @code{--pskkey} parameter, it will query only for the password during
@@ -179,16 +179,16 @@ use @code{gnutls-serv} as a simple HTTPS server.
 
 The most basic server can be started as:
 
address@hidden
address@hidden
 gnutls-serv --http
address@hidden smallexample
address@hidden example
 
 It will only support anonymous ciphersuites, which many TLS clients
 refuse to use.
 
 The next step is to add support for X.509.  First we generate a CA:
 
address@hidden
address@hidden
 $ certtool --generate-privkey > x509-ca-key.pem
 $ echo 'cn = GnuTLS test CA' > ca.tmpl
 $ echo 'ca' >> ca.tmpl
@@ -196,7 +196,7 @@ $ echo 'cert_signing_key' >> ca.tmpl
 $ certtool --generate-self-signed --load-privkey x509-ca-key.pem \
   --template ca.tmpl --outfile x509-ca.pem
 ...
address@hidden smallexample
address@hidden example
 
 Then generate a server certificate.  Remember to change the dns_name
 value to the name of your server host, or skip that command to avoid
@@ -235,15 +235,15 @@ To be able to import the client key/certificate into some
 applications, you will need to convert them into a PKCS#12 structure.
 This also encrypts the security sensitive key with a password.
 
address@hidden
address@hidden
 $ certtool --to-p12 --load-ca-certificate x509-ca.pem \
   --load-privkey x509-client-key.pem --load-certificate x509-client.pem \
   --outder --outfile x509-client.p12
address@hidden smallexample
address@hidden example
 
 For icing, we'll create a proxy certificate for the client too.
 
address@hidden
address@hidden
 $ certtool --generate-privkey > x509-proxy-key.pem
 $ echo 'cn = GnuTLS test client proxy' > proxy.tmpl
 $ certtool --generate-proxy --load-privkey x509-proxy-key.pem \
@@ -251,16 +251,16 @@ $ certtool --generate-proxy --load-privkey 
x509-proxy-key.pem \
   --load-certificate x509-client.pem --template proxy.tmpl \
   --outfile x509-proxy.pem
 ...
address@hidden smallexample
address@hidden example
 
 Then start the server again:
 
address@hidden
address@hidden
 $ gnutls-serv --http \
             --x509cafile x509-ca.pem \
             --x509keyfile x509-server-key.pem \
             --x509certfile x509-server.pem
address@hidden smallexample
address@hidden example
 
 Try connecting to the server using your web browser.  Note that the
 server listens to port 5556 by default.
@@ -269,62 +269,62 @@ While you are at it, to allow connections using DSA, you 
can also
 create a DSA key and certificate for the server.  These credentials
 will be used in the final example below.
 
address@hidden
address@hidden
 $ certtool --generate-privkey --dsa > x509-server-key-dsa.pem
 $ certtool --generate-certificate --load-privkey x509-server-key-dsa.pem \
   --load-ca-certificate x509-ca.pem --load-ca-privkey x509-ca-key.pem \
   --template server.tmpl --outfile x509-server-dsa.pem
 ...
address@hidden smallexample
address@hidden example
 
 The next step is to create OpenPGP credentials for the server.
 
address@hidden
address@hidden
 gpg --gen-key
 ...enter whatever details you want, use 'test.gnutls.org' as name...
address@hidden smallexample
address@hidden example
 
 Make a note of the OpenPGP key identifier of the newly generated key,
 here it was @code{5D1D14D8}.  You will need to export the key for
 GnuTLS to be able to use it.
 
address@hidden
address@hidden
 gpg -a --export 5D1D14D8 > openpgp-server.txt
 gpg --export 5D1D14D8 > openpgp-server.bin
 gpg --export-secret-keys 5D1D14D8 > openpgp-server-key.bin
 gpg -a --export-secret-keys 5D1D14D8 > openpgp-server-key.txt
address@hidden smallexample
address@hidden example
 
 Let's start the server with support for OpenPGP credentials:
 
address@hidden
address@hidden
 gnutls-serv --http \
             --pgpkeyfile openpgp-server-key.txt \
             --pgpcertfile openpgp-server.txt
address@hidden smallexample
address@hidden example
 
 The next step is to add support for SRP authentication. This requires
 an SRP password file (see @ref{Invoking srptool}).
 To start the server with SRP support:
 
address@hidden
address@hidden
 gnutls-serv --http \
             --srppasswdconf srp-tpasswd.conf \
             --srppasswd srp-passwd.txt
address@hidden smallexample
address@hidden example
 
 Let's also start a server with support for PSK. This would require
 a password file created with @code{psktool} (see @ref{Invoking psktool}).
 
address@hidden
address@hidden
 gnutls-serv --http \
             --pskpasswd psk-passwd.txt
address@hidden smallexample
address@hidden example
 
 Finally, we start the server with all the earlier parameters and you
 get this command:
 
address@hidden
address@hidden
 gnutls-serv --http \
             --x509cafile x509-ca.pem \
             --x509keyfile x509-server-key.pem \
@@ -336,7 +336,7 @@ gnutls-serv --http \
             --srppasswdconf srp-tpasswd.conf \
             --srppasswd srp-passwd.txt \
             --pskpasswd psk-passwd.txt
address@hidden smallexample
address@hidden example
 
 
 @node The gnutls-cli-debug tool
diff --git a/doc/cha-shared-key.texi b/doc/cha-shared-key.texi
index 50f4585..eb62959 100644
--- a/doc/cha-shared-key.texi
+++ b/doc/cha-shared-key.texi
@@ -83,26 +83,26 @@ and @code{tpasswd.conf} which holds generators and primes.
 To create tpasswd.conf which holds the generator and prime values for
 the @acronym{SRP} protocol, run:
 
address@hidden
address@hidden
 $ srptool --create-conf /etc/tpasswd.conf
address@hidden smallexample
address@hidden example
 
 This command will create /etc/tpasswd and will add user 'test' (you
 will also be prompted for a password).  Verifiers are stored in a way that
 is compatible with libsrp.
 
address@hidden
address@hidden
 $ srptool --passwd /etc/tpasswd \
     --passwd-conf /etc/tpasswd.conf -u test
address@hidden smallexample
address@hidden example
 
 This command will check against a password.  If the password matches
 the one in /etc/tpasswd you will get an ok.
 
address@hidden
address@hidden
 $ srptool --passwd /etc/tpasswd \
     --passwd-conf /etc/tpasswd.conf --verify -u test
address@hidden smallexample
address@hidden example
 
 @node PSK authentication
 @section PSK authentication
@@ -153,7 +153,7 @@ This is a program to manage @acronym{PSK} username and keys.
 It will generate random keys for the indicated username, 
 using a simple password file format.
 
address@hidden
address@hidden
 PSKtool help
 Usage : psktool [options]
      -u, --username username
@@ -162,19 +162,19 @@ Usage : psktool [options]
      -s, --keysize SIZE       specify the key size in bytes.
      -v, --version            prints the program's version number
      -h, --help               shows this help text
address@hidden smallexample
address@hidden example
 
 The generation of a PSK password file is illustrated in the example below. 
 The password is provided in the prompt.
 
address@hidden
address@hidden
 $ ./psktool -u psk_identity -p psks.txt
 Generating a random key for user 'psk_identity'
 Key stored to psks.txt
 $ cat psks.txt
 psk_identity:88f3824b3e5659f52d00e959bacab954b6540344
 $
address@hidden smallexample
address@hidden example
 
 @node Anonymous authentication
 @section Anonymous authentication
diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am
index 0ed1eae..aac8421 100644
--- a/doc/examples/Makefile.am
+++ b/doc/examples/Makefile.am
@@ -41,11 +41,11 @@ LDADD = libexamples.la                              \
 CXX_LDADD = $(LDADD) \
        ../../lib/libgnutlsxx.la
 
-noinst_PROGRAMS = ex-client-resume ex-client-udp
-noinst_PROGRAMS += ex-cert-select ex-rfc2818
+noinst_PROGRAMS = ex-client-resume ex-client-dtls
+noinst_PROGRAMS += ex-cert-select ex-client-x509
 
 if ENABLE_PKI
-noinst_PROGRAMS += ex-crq ex-serv1
+noinst_PROGRAMS += ex-crq ex-serv-x509 ex-serv-dtls
 endif
 
 if ENABLE_CXX
@@ -55,7 +55,7 @@ noinst_PROGRAMS += ex-cxx
 endif
 
 if ENABLE_ANON
-noinst_PROGRAMS += ex-client1 ex-serv-anon
+noinst_PROGRAMS += ex-client-anon ex-serv-anon
 endif
 
 if ENABLE_OPENPGP
diff --git a/doc/examples/ex-client1.c b/doc/examples/ex-client-anon.c
similarity index 95%
rename from doc/examples/ex-client1.c
rename to doc/examples/ex-client-anon.c
index 322e400..8c06bda 100644
--- a/doc/examples/ex-client1.c
+++ b/doc/examples/ex-client-anon.c
@@ -55,7 +55,11 @@ main (void)
 
   /* Perform the TLS handshake
    */
-  ret = gnutls_handshake (session);
+  do
+    {
+      ret = gnutls_handshake (session);
+    }
+  while (gnutls_error_is_fatal (ret) == 0);
 
   if (ret < 0)
     {
diff --git a/doc/examples/ex-client-udp.c b/doc/examples/ex-client-dtls.c
similarity index 92%
rename from doc/examples/ex-client-udp.c
rename to doc/examples/ex-client-dtls.c
index 7a0721a..222762a 100644
--- a/doc/examples/ex-client-udp.c
+++ b/doc/examples/ex-client-dtls.c
@@ -59,6 +59,8 @@ main (void)
 
   /* put the x509 credentials to the current session */
   gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
+  gnutls_server_name_set (session, GNUTLS_NAME_DNS, "my_host_name", 
+                          strlen("my_host_name"));
 
   /* connect to the peer */
   sd = udp_connect ();
@@ -69,7 +71,11 @@ main (void)
   gnutls_dtls_set_mtu (session, 1000);
 
   /* Perform the TLS handshake */
-  ret = gnutls_handshake (session);
+  do
+    {
+      ret = gnutls_handshake (session);
+    }
+  while (gnutls_error_is_fatal (ret) == 0);
 
   if (ret < 0)
     {
diff --git a/doc/examples/ex-client-psk.c b/doc/examples/ex-client-psk.c
index 2264f07..7c0bd7e 100644
--- a/doc/examples/ex-client-psk.c
+++ b/doc/examples/ex-client-psk.c
@@ -65,7 +65,11 @@ main (void)
 
   /* Perform the TLS handshake
    */
-  ret = gnutls_handshake (session);
+  do
+    {
+      ret = gnutls_handshake (session);
+    }
+  while (gnutls_error_is_fatal (ret) == 0);
 
   if (ret < 0)
     {
diff --git a/doc/examples/ex-client-resume.c b/doc/examples/ex-client-resume.c
index 9e6e9b6..5aeae58 100644
--- a/doc/examples/ex-client-resume.c
+++ b/doc/examples/ex-client-resume.c
@@ -63,7 +63,11 @@ main (void)
 
       /* Perform the TLS handshake
        */
-      ret = gnutls_handshake (session);
+      do
+        {
+          ret = gnutls_handshake (session);
+        }
+      while (gnutls_error_is_fatal (ret) == 0);
 
       if (ret < 0)
         {
diff --git a/doc/examples/ex-client-srp.c b/doc/examples/ex-client-srp.c
index b8ecc2b..5a753ab 100644
--- a/doc/examples/ex-client-srp.c
+++ b/doc/examples/ex-client-srp.c
@@ -62,7 +62,11 @@ main (void)
 
   /* Perform the TLS handshake
    */
-  ret = gnutls_handshake (session);
+  do
+    {
+      ret = gnutls_handshake (session);
+    }
+  while (gnutls_error_is_fatal (ret) == 0);
 
   if (ret < 0)
     {
diff --git a/doc/examples/ex-rfc2818.c b/doc/examples/ex-client-x509.c
similarity index 97%
rename from doc/examples/ex-rfc2818.c
rename to doc/examples/ex-client-x509.c
index f7aa08d..c82df65 100644
--- a/doc/examples/ex-rfc2818.c
+++ b/doc/examples/ex-client-x509.c
@@ -46,6 +46,8 @@ int main (void)
   gnutls_init (&session, GNUTLS_CLIENT);
 
   gnutls_session_set_ptr (session, (void *) "my_host_name");
+  gnutls_server_name_set (session, GNUTLS_NAME_DNS, "my_host_name", 
+                          strlen("my_host_name"));
 
   /* Use default priorities */
   ret = gnutls_priority_set_direct (session, "NORMAL", &err);
diff --git a/doc/examples/ex-serv-anon.c b/doc/examples/ex-serv-anon.c
index ade01f4..93c8a70 100644
--- a/doc/examples/ex-serv-anon.c
+++ b/doc/examples/ex-serv-anon.c
@@ -116,7 +116,13 @@ main (void)
                          sizeof (topbuf)), ntohs (sa_cli.sin_port));
 
       gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
-      ret = gnutls_handshake (session);
+
+      do
+        {
+          ret = gnutls_handshake (session);
+        }
+      while (gnutls_error_is_fatal (ret) == 0);
+
       if (ret < 0)
         {
           close (sd);
diff --git a/doc/examples/ex-serv-dtls.c b/doc/examples/ex-serv-dtls.c
new file mode 100644
index 0000000..52c96c3
--- /dev/null
+++ b/doc/examples/ex-serv-dtls.c
@@ -0,0 +1,432 @@
+/* This example code is placed in the public domain. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/select.h>
+#include <netdb.h>
+#include <string.h>
+#include <unistd.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/dtls.h>
+
+#define KEYFILE "key.pem"
+#define CERTFILE "cert.pem"
+#define CAFILE "ca.pem"
+#define CRLFILE "crl.pem"
+
+/* This is a sample DTLS echo server, using X.509 authentication.
+ * Note that error checking is minimal to simplify the example.
+ */
+
+#define MAX_BUFFER 1024
+#define PORT 5556
+
+typedef struct
+{
+  gnutls_session_t session;
+  int fd;
+  struct sockaddr *cli_addr;
+  socklen_t cli_addr_size;
+} priv_data_st;
+
+static int pull_timeout_func (gnutls_transport_ptr_t ptr, unsigned int ms);
+static ssize_t push_func (gnutls_transport_ptr_t p, const void *data,
+                          size_t size);
+static ssize_t pull_func (gnutls_transport_ptr_t p, void *data, size_t size);
+static const char *human_addr (const struct sockaddr *sa, socklen_t salen,
+                               char *buf, size_t buflen);
+static int wait_for_connection (int fd);
+static gnutls_session_t initialize_tls_session (void);
+static int generate_dh_params (void);
+
+/* Use global credentials and parameters to simplify
+ * the example. */
+static gnutls_certificate_credentials_t x509_cred;
+static gnutls_priority_t priority_cache;
+static gnutls_dh_params_t dh_params;
+
+int
+main (void)
+{
+  int listen_sd;
+  int sock, ret;
+  struct sockaddr_in sa_serv;
+  struct sockaddr_in cli_addr;
+  socklen_t cli_addr_size;
+  gnutls_session_t session;
+  char buffer[MAX_BUFFER];
+  priv_data_st priv;
+  gnutls_datum_t cookie_key;
+  gnutls_dtls_prestate_st prestate;
+  int mtu = 1400;
+  unsigned char sequence[8];
+
+  /* this must be called once in the program
+   */
+  gnutls_global_init ();
+
+  gnutls_certificate_allocate_credentials (&x509_cred);
+  gnutls_certificate_set_x509_trust_file (x509_cred, CAFILE,
+                                          GNUTLS_X509_FMT_PEM);
+
+  gnutls_certificate_set_x509_crl_file (x509_cred, CRLFILE,
+                                        GNUTLS_X509_FMT_PEM);
+
+  ret = gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE,
+                                        GNUTLS_X509_FMT_PEM);
+  if (ret < 0)
+    {
+      printf("No certificate or key were found\n");
+      exit(1);
+    }
+
+  generate_dh_params ();
+
+  gnutls_certificate_set_dh_params (x509_cred, dh_params);
+
+  gnutls_priority_init (&priority_cache,
+                        "NORMAL:-VERS-TLS-ALL:+VERS-DTLS1.0", NULL);
+
+  gnutls_key_generate (&cookie_key, GNUTLS_COOKIE_KEY_SIZE);
+
+  /* Socket operations
+   */
+  listen_sd = socket (AF_INET, SOCK_DGRAM, 0);
+
+  memset (&sa_serv, '\0', sizeof (sa_serv));
+  sa_serv.sin_family = AF_INET;
+  sa_serv.sin_addr.s_addr = INADDR_ANY;
+  sa_serv.sin_port = htons (PORT);
+
+  { /* DTLS requires the IP don't fragment (DF) bit to be set */
+#if defined(IP_DONTFRAG)
+    int optval = 1;
+    setsockopt (listen_sd, IPPROTO_IP, IP_DONTFRAG,
+                (const void *) &optval, sizeof (optval));
+#elif defined(IP_MTU_DISCOVER)
+    int optval = IP_PMTUDISC_DO;
+    setsockopt(listen_sd, IPPROTO_IP, IP_MTU_DISCOVER, 
+               (const void*) &optval, sizeof (optval));
+#endif
+  }
+
+  bind (listen_sd, (struct sockaddr *) &sa_serv, sizeof (sa_serv));
+
+  printf ("UDP server ready. Listening to port '%d'.\n\n", PORT);
+
+  for (;;)
+    {
+      printf ("Waiting for connection...\n");
+      sock = wait_for_connection (listen_sd);
+      if (sock < 0)
+        continue;
+
+      cli_addr_size = sizeof (cli_addr);
+      ret = recvfrom (sock, buffer, sizeof (buffer), MSG_PEEK,
+                      (struct sockaddr *) &cli_addr, &cli_addr_size);
+      if (ret > 0)
+        {
+          memset (&prestate, 0, sizeof (prestate));
+          ret = gnutls_dtls_cookie_verify (&cookie_key, &cli_addr,
+                                           sizeof (cli_addr), buffer, ret,
+                                           &prestate);
+          if (ret < 0)          /* cookie not valid */
+            {
+              priv_data_st s;
+
+              memset (&s, 0, sizeof (s));
+              s.fd = sock;
+              s.cli_addr = (void *) &cli_addr;
+              s.cli_addr_size = sizeof (cli_addr);
+
+              printf ("Sending hello verify request to %s\n",
+                      human_addr ((struct sockaddr *) &cli_addr,
+                                  sizeof (cli_addr), buffer,
+                                  sizeof (buffer)));
+
+              gnutls_dtls_cookie_send (&cookie_key, &cli_addr,
+                                       sizeof (cli_addr), &prestate,
+                                       (gnutls_transport_ptr_t) & s,
+                                       push_func);
+
+              /* discard peeked data */
+              recvfrom (sock, buffer, sizeof (buffer), 0,
+                        (struct sockaddr *) &cli_addr, &cli_addr_size);
+              usleep (100);
+              continue;
+            }
+          printf ("Accepted connection from %s\n",
+                  human_addr ((struct sockaddr *)
+                              &cli_addr, sizeof (cli_addr), buffer,
+                              sizeof (buffer)));
+        }
+      else
+        continue;
+
+      session = initialize_tls_session ();
+      gnutls_dtls_prestate_set (session, &prestate);
+      gnutls_dtls_set_mtu (session, mtu);
+
+      priv.session = session;
+      priv.fd = sock;
+      priv.cli_addr = (struct sockaddr *) &cli_addr;
+      priv.cli_addr_size = sizeof (cli_addr);
+
+      gnutls_transport_set_ptr (session, &priv);
+      gnutls_transport_set_push_function (session, push_func);
+      gnutls_transport_set_pull_function (session, pull_func);
+      gnutls_transport_set_pull_timeout_function (session, pull_timeout_func);
+
+      do
+        {
+          ret = gnutls_handshake (session);
+        }
+      while (gnutls_error_is_fatal (ret) == 0);
+
+      if (ret < 0)
+        {
+          fprintf (stderr, "Error in handshake(): %s\n",
+                   gnutls_strerror (ret));
+          gnutls_deinit (session);
+          continue;
+        }
+
+      printf ("- Handshake was completed\n");
+
+      for (;;)
+        {
+          do
+            {
+              ret = gnutls_record_recv_seq (session, buffer, MAX_BUFFER,
+                                            sequence);
+            }
+          while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
+
+          if (ret < 0)
+            {
+              fprintf (stderr, "Error in recv(): %s\n",
+                       gnutls_strerror (ret));
+              break;
+            }
+          if (ret == 0)
+            {
+              printf ("EOF\n\n");
+              break;
+            }
+          buffer[ret] = 0;
+          printf ("received[%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x]: %s\n",
+                  sequence[0], sequence[1], sequence[2], sequence[3],
+                  sequence[4], sequence[5], sequence[6], sequence[7], buffer);
+
+          /* reply back */
+          ret = gnutls_record_send (session, buffer, ret);
+          if (ret < 0)
+            {
+              fprintf (stderr, "Error in send(): %s\n",
+                       gnutls_strerror (ret));
+              break;
+            }
+        }
+
+      gnutls_bye (session, GNUTLS_SHUT_WR);
+      gnutls_deinit (session);
+
+    }
+  close (listen_sd);
+
+  gnutls_certificate_free_credentials (x509_cred);
+  gnutls_priority_deinit (priority_cache);
+
+  gnutls_global_deinit ();
+
+  return 0;
+
+}
+
+static int
+wait_for_connection (int fd)
+{
+  fd_set rd, wr;
+  int n;
+
+  FD_ZERO (&rd);
+  FD_ZERO (&wr);
+
+  FD_SET (fd, &rd);
+
+  /* waiting part */
+  n = select (fd + 1, &rd, &wr, NULL, NULL);
+  if (n == -1 && errno == EINTR)
+    return -1;
+  if (n < 0)
+    {
+      perror ("select()");
+      exit (1);
+    }
+
+  return fd;
+}
+
+/* Wait for data to be received within a timeout period in milliseconds
+ */
+static int
+pull_timeout_func (gnutls_transport_ptr_t ptr, unsigned int ms)
+{
+  fd_set rfds;
+  struct timeval tv;
+  priv_data_st *priv = ptr;
+  struct sockaddr_in cli_addr;
+  socklen_t cli_addr_size;
+  int ret;
+  char c;
+
+  FD_ZERO (&rfds);
+  FD_SET (priv->fd, &rfds);
+
+  tv.tv_sec = 0;
+  tv.tv_usec = ms * 1000;
+
+  ret = select (priv->fd + 1, &rfds, NULL, NULL, &tv);
+
+  if (ret <= 0)
+    return ret;
+
+  /* only report ok if the next message is from the peer we expect
+   * from 
+   */
+  cli_addr_size = sizeof (cli_addr);
+  ret =
+    recvfrom (priv->fd, &c, 1, MSG_PEEK, (struct sockaddr *) &cli_addr,
+              &cli_addr_size);
+  if (ret > 0)
+    {
+      if (cli_addr_size == priv->cli_addr_size
+          && memcmp (&cli_addr, priv->cli_addr, sizeof (cli_addr)) == 0)
+        return 1;
+    }
+
+  return 0;
+}
+
+static ssize_t
+push_func (gnutls_transport_ptr_t p, const void *data, size_t size)
+{
+  priv_data_st *priv = p;
+
+  return sendto (priv->fd, data, size, 0, priv->cli_addr,
+                 priv->cli_addr_size);
+}
+
+static ssize_t
+pull_func (gnutls_transport_ptr_t p, void *data, size_t size)
+{
+  priv_data_st *priv = p;
+  struct sockaddr_in cli_addr;
+  socklen_t cli_addr_size;
+  char buffer[64];
+  int ret;
+
+  cli_addr_size = sizeof (cli_addr);
+  ret =
+    recvfrom (priv->fd, data, size, 0, (struct sockaddr *) &cli_addr,
+              &cli_addr_size);
+  if (ret == -1)
+    return ret;
+
+  if (cli_addr_size == priv->cli_addr_size
+      && memcmp (&cli_addr, priv->cli_addr, sizeof (cli_addr)) == 0)
+    return ret;
+
+  printf ("Denied connection from %s\n",
+          human_addr ((struct sockaddr *)
+                      &cli_addr, sizeof (cli_addr), buffer, sizeof (buffer)));
+
+  gnutls_transport_set_errno (priv->session, EAGAIN);
+  return -1;
+}
+
+static const char *
+human_addr (const struct sockaddr *sa, socklen_t salen,
+            char *buf, size_t buflen)
+{
+  const char *save_buf = buf;
+  size_t l;
+
+  if (!buf || !buflen)
+    return NULL;
+
+  *buf = '\0';
+
+  switch (sa->sa_family)
+    {
+#if HAVE_IPV6
+    case AF_INET6:
+      snprintf (buf, buflen, "IPv6 ");
+      break;
+#endif
+
+    case AF_INET:
+      snprintf (buf, buflen, "IPv4 ");
+      break;
+    }
+
+  l = strlen (buf);
+  buf += l;
+  buflen -= l;
+
+  if (getnameinfo (sa, salen, buf, buflen, NULL, 0, NI_NUMERICHOST) != 0)
+    return NULL;
+
+  l = strlen (buf);
+  buf += l;
+  buflen -= l;
+
+  strncat (buf, " port ", buflen);
+
+  l = strlen (buf);
+  buf += l;
+  buflen -= l;
+
+  if (getnameinfo (sa, salen, NULL, 0, buf, buflen, NI_NUMERICSERV) != 0)
+    return NULL;
+
+  return save_buf;
+}
+
+static gnutls_session_t
+initialize_tls_session (void)
+{
+  gnutls_session_t session;
+
+  gnutls_init (&session, GNUTLS_SERVER | GNUTLS_DATAGRAM);
+
+  gnutls_priority_set (session, priority_cache);
+
+  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, x509_cred);
+
+  return session;
+}
+
+static int
+generate_dh_params (void)
+{
+  int bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LOW);
+
+  /* Generate Diffie-Hellman parameters - for use with DHE
+   * kx algorithms. When short bit length is used, it might
+   * be wise to regenerate parameters often.
+   */
+  gnutls_dh_params_init (&dh_params);
+  gnutls_dh_params_generate2 (dh_params, bits);
+
+  return 0;
+}
diff --git a/doc/examples/ex-serv-srp.c b/doc/examples/ex-serv-srp.c
index 5dbd8cf..0cff30c 100644
--- a/doc/examples/ex-serv-srp.c
+++ b/doc/examples/ex-serv-srp.c
@@ -117,7 +117,13 @@ main (void)
                          sizeof (topbuf)), ntohs (sa_cli.sin_port));
 
       gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
-      ret = gnutls_handshake (session);
+
+      do
+        {
+          ret = gnutls_handshake (session);
+        }
+      while (gnutls_error_is_fatal (ret) == 0);
+
       if (ret < 0)
         {
           close (sd);
diff --git a/doc/examples/ex-serv1.c b/doc/examples/ex-serv-x509.c
similarity index 80%
rename from doc/examples/ex-serv1.c
rename to doc/examples/ex-serv-x509.c
index 7166657..5383fb3 100644
--- a/doc/examples/ex-serv1.c
+++ b/doc/examples/ex-serv-x509.c
@@ -23,12 +23,8 @@
 /* This is a sample TLS 1.0 echo server, using X.509 authentication.
  */
 
-
-#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
 
 /* These are global */
 gnutls_certificate_credentials_t x509_cred;
@@ -45,14 +41,10 @@ initialize_tls_session (void)
 
   gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, x509_cred);
 
-  /* request client certificate if any.
-   */
-  gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUEST);
-
-  /* Set maximum compatibility mode. This is only suggested on public 
webservers
-   * that need to trade security for compatibility
+  /* We don't request any certificate from the client.
+   * If we did we would need to verify it.
    */
-  gnutls_session_enable_compatibility_mode (session);
+  gnutls_certificate_server_set_request (session, GNUTLS_CERT_IGNORE);
 
   return session;
 }
@@ -62,16 +54,14 @@ static gnutls_dh_params_t dh_params;
 static int
 generate_dh_params (void)
 {
+  int bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LOW);
 
   /* Generate Diffie-Hellman parameters - for use with DHE
    * kx algorithms. When short bit length is used, it might
-   * be wise to regenerate parameters.
-   *
-   * Check the ex-serv-export.c example for using static
-   * parameters.
+   * be wise to regenerate parameters often.
    */
   gnutls_dh_params_init (&dh_params);
-  gnutls_dh_params_generate2 (dh_params, DH_BITS);
+  gnutls_dh_params_generate2 (dh_params, bits);
 
   return 0;
 }
@@ -79,7 +69,7 @@ generate_dh_params (void)
 int
 main (void)
 {
-  int err, listen_sd;
+  int listen_sd;
   int sd, ret;
   struct sockaddr_in sa_serv;
   struct sockaddr_in sa_cli;
@@ -100,12 +90,17 @@ main (void)
   gnutls_certificate_set_x509_crl_file (x509_cred, CRLFILE,
                                         GNUTLS_X509_FMT_PEM);
 
-  gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE,
+  ret = gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE,
                                         GNUTLS_X509_FMT_PEM);
+  if (ret < 0)
+    {
+      printf("No certificate or key were found\n");
+      exit(1);
+    }
 
   generate_dh_params ();
 
-  gnutls_priority_init (&priority_cache, "NORMAL", NULL);
+  gnutls_priority_init (&priority_cache, "PERFORMANCE:%SERVER_PRECEDENCE", 
NULL);
 
 
   gnutls_certificate_set_dh_params (x509_cred, dh_params);
@@ -113,7 +108,6 @@ main (void)
   /* Socket operations
    */
   listen_sd = socket (AF_INET, SOCK_STREAM, 0);
-  SOCKET_ERR (listen_sd, "socket");
 
   memset (&sa_serv, '\0', sizeof (sa_serv));
   sa_serv.sin_family = AF_INET;
@@ -123,10 +117,9 @@ main (void)
   setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval,
               sizeof (int));
 
-  err = bind (listen_sd, (SA *) & sa_serv, sizeof (sa_serv));
-  SOCKET_ERR (err, "bind");
-  err = listen (listen_sd, 1024);
-  SOCKET_ERR (err, "listen");
+  bind (listen_sd, (struct sockaddr *) & sa_serv, sizeof (sa_serv));
+
+  listen (listen_sd, 1024);
 
   printf ("Server ready. Listening to port '%d'.\n\n", PORT);
 
@@ -135,14 +128,20 @@ main (void)
     {
       session = initialize_tls_session ();
 
-      sd = accept (listen_sd, (SA *) & sa_cli, &client_len);
+      sd = accept (listen_sd, (struct sockaddr *) & sa_cli, &client_len);
 
       printf ("- connection from %s, port %d\n",
               inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf,
                          sizeof (topbuf)), ntohs (sa_cli.sin_port));
 
       gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
-      ret = gnutls_handshake (session);
+
+      do
+        {
+          ret = gnutls_handshake (session);
+        }
+      while (gnutls_error_is_fatal (ret) == 0);
+
       if (ret < 0)
         {
           close (sd);
diff --git a/doc/examples/udp.c b/doc/examples/udp.c
index 3eb567a..0c48ac1 100644
--- a/doc/examples/udp.c
+++ b/doc/examples/udp.c
@@ -13,9 +13,7 @@
 #include <netinet/in.h>
 #include <unistd.h>
 
-#define SA struct sockaddr
-
-/* tcp.c */
+/* udp.c */
 int udp_connect (void);
 void udp_close (int sd);
 
@@ -27,7 +25,7 @@ udp_connect (void)
 {
   const char *PORT = "5557";
   const char *SERVER = "127.0.0.1";
-  int err, sd;
+  int err, sd, optval;
   struct sockaddr_in sa;
 
   /* connects to server
@@ -39,7 +37,17 @@ udp_connect (void)
   sa.sin_port = htons (atoi (PORT));
   inet_pton (AF_INET, SERVER, &sa.sin_addr);
 
-  err = connect (sd, (SA *) & sa, sizeof (sa));
+#if defined(IP_DONTFRAG)
+  optval = 1;
+  setsockopt (sd, IPPROTO_IP, IP_DONTFRAG,
+              (const void *) &optval, sizeof (optval));
+#elif defined(IP_MTU_DISCOVER)
+  optval = IP_PMTUDISC_DO;
+  setsockopt(sd, IPPROTO_IP, IP_MTU_DISCOVER, 
+             (const void*) &optval, sizeof (optval));
+#endif
+
+  err = connect (sd, (struct sockaddr *) & sa, sizeof (sa));
   if (err < 0)
     {
       fprintf (stderr, "Connect error\n");
diff --git a/lib/Makefile.am b/lib/Makefile.am
index d944c2f..7fd533a 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -20,7 +20,7 @@
 
 ACLOCAL_AMFLAGS = -I ../m4 -I ../gl/m4
 
-SUBDIRS = includes x509 accelerated auth ext algorithms
+SUBDIRS = includes x509 accelerated auth ext algorithms extras
 if ENABLE_MINITASN1
 SUBDIRS += minitasn1
 endif
@@ -114,6 +114,7 @@ libgnutls_la_LDFLAGS = -no-undefined \
 libgnutls_la_LIBADD = ../gl/libgnu.la x509/libgnutls_x509.la \
        accelerated/libaccelerated.la ext/libgnutls_ext.la \
        auth/libgnutls_auth.la algorithms/libgnutls_alg.la \
+       extras/libgnutls_extras.la \
        $(LTLIBZ)  $(LTLIBINTL) $(LIBSOCKET) $(LTLIBDL) \
        $(LTLIBPTHREAD) $(P11_KIT_LIBS)
 
diff --git a/lib/algorithms/ciphers.c b/lib/algorithms/ciphers.c
index 198844f..f8e1469 100644
--- a/lib/algorithms/ciphers.c
+++ b/lib/algorithms/ciphers.c
@@ -43,7 +43,7 @@ typedef struct gnutls_cipher_entry gnutls_cipher_entry;
  * View first: "The order of encryption and authentication for
  * protecting communications" by Hugo Krawczyk - CRYPTO 2001
  *
- * Make sure to updated MAX_CIPHER_BLOCK_SIZE and MAX_CIPHER_KEY_SIZE as well.
+ * Make sure to update MAX_CIPHER_BLOCK_SIZE and MAX_CIPHER_KEY_SIZE as well.
  */
 static const gnutls_cipher_entry algorithms[] = {
   {"AES-256-CBC", GNUTLS_CIPHER_AES_256_CBC, 16, 32, CIPHER_BLOCK, 16, 0, 0},
@@ -203,7 +203,7 @@ gnutls_cipher_get_name (gnutls_cipher_algorithm_t algorithm)
 
 /**
  * gnutls_cipher_get_id:
- * @name: is a MAC algorithm name
+ * @name: is a cipher algorithm name
  *
  * The names are compared in a case insensitive way.
  *
diff --git a/lib/algorithms/protocols.c b/lib/algorithms/protocols.c
index 6d6b04c..e59c8fd 100644
--- a/lib/algorithms/protocols.c
+++ b/lib/algorithms/protocols.c
@@ -162,7 +162,7 @@ gnutls_protocol_get_id (const char *name)
  *
  * Get a list of supported protocols, e.g. SSL 3.0, TLS 1.0 etc.
  *
- * This function is not threat safe.
+ * This function is not thread safe.
  *
  * Returns: a (0)-terminated list of #gnutls_protocol_t integers
  * indicating the available protocols.
diff --git a/lib/algorithms/secparams.c b/lib/algorithms/secparams.c
index ba6c7d5..456e3a1 100644
--- a/lib/algorithms/secparams.c
+++ b/lib/algorithms/secparams.c
@@ -127,7 +127,7 @@ _gnutls_pk_bits_to_subgroup_bits (unsigned int pk_bits)
  * Convert a #gnutls_sec_param_t value to a string.
  *
  * Returns: a pointer to a string that contains the name of the
- *   specified public key algorithm, or %NULL.
+ *   specified security level, or %NULL.
  *
  * Since: 2.12.0
  **/
diff --git a/lib/openpgp/Makefile.am b/lib/extras/Makefile.am
similarity index 85%
copy from lib/openpgp/Makefile.am
copy to lib/extras/Makefile.am
index 4d06564..b973b88 100644
--- a/lib/openpgp/Makefile.am
+++ b/lib/extras/Makefile.am
@@ -32,9 +32,6 @@ if ENABLE_MINITASN1
 AM_CPPFLAGS += -I$(srcdir)/../minitasn1
 endif
 
-noinst_LTLIBRARIES = libgnutls_openpgp.la
+noinst_LTLIBRARIES = libgnutls_extras.la
 
-COBJECTS = pgp.c pgpverify.c extras.c compat.c privkey.c output.c      \
-       gnutls_openpgp.c
-
-libgnutls_openpgp_la_SOURCES = $(COBJECTS) openpgp_int.h gnutls_openpgp.h
+libgnutls_extras_la_SOURCES = randomart.c
diff --git a/lib/extras/randomart.c b/lib/extras/randomart.c
new file mode 100644
index 0000000..cf8d72e
--- /dev/null
+++ b/lib/extras/randomart.c
@@ -0,0 +1,147 @@
+/* $OpenBSD: key.c,v 1.98 2011/10/18 04:58:26 djm Exp $ */
+/*
+ * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <gnutls_int.h>
+#include <gnutls_errors.h>
+#include <randomart.h>
+
+/*
+ * Draw an ASCII-Art representing the fingerprint so human brain can
+ * profit from its built-in pattern recognition ability.
+ * This technique is called "random art" and can be found in some
+ * scientific publications like this original paper:
+ *
+ * "Hash Visualization: a New Technique to improve Real-World Security",
+ * Perrig A. and Song D., 1999, International Workshop on Cryptographic
+ * Techniques and E-Commerce (CrypTEC '99)
+ * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
+ *
+ * The subject came up in a talk by Dan Kaminsky, too.
+ *
+ * If you see the picture is different, the key is different.
+ * If the picture looks the same, you still know nothing.
+ *
+ * The algorithm used here is a worm crawling over a discrete plane,
+ * leaving a trace (augmenting the field) everywhere it goes.
+ * Movement is taken from dgst_raw 2bit-wise.  Bumping into walls
+ * makes the respective movement vector be ignored for this turn.
+ * Graphs are not unambiguous, because circles in graphs can be
+ * walked in either direction.
+ */
+
+/*
+ * Field sizes for the random art.  Have to be odd, so the starting point
+ * can be in the exact middle of the picture, and FLDBASE should be >=8 .
+ * Else pictures would be too dense, and drawing the frame would
+ * fail, too, because the key type would not fit in anymore.
+ */
+#define        FLDBASE         8
+#define        FLDSIZE_Y       (FLDBASE + 1)
+#define        FLDSIZE_X       (FLDBASE * 2 + 1)
+char *
+key_fingerprint_randomart (uint8_t * dgst_raw, u_int dgst_raw_len,
+                           const char *key_type, unsigned int key_size)
+{
+  /*
+   * Chars to be used after each other every time the worm
+   * intersects with itself.  Matter of taste.
+   */
+  const char augmentation_string[] = " address@hidden&#/^SE";
+  char *retval, *p;
+  uint8_t field[FLDSIZE_X][FLDSIZE_Y];
+  u_int i, b;
+  int x, y;
+  const size_t len = sizeof(augmentation_string) - 2;
+
+  retval = gnutls_calloc (1, (FLDSIZE_X + 3) * (FLDSIZE_Y + 2));
+  if (retval == NULL)
+    {
+      gnutls_assert();
+      return NULL;
+    }
+
+  /* initialize field */
+  memset (field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof (char));
+  x = FLDSIZE_X / 2;
+  y = FLDSIZE_Y / 2;
+
+  /* process raw key */
+  for (i = 0; i < dgst_raw_len; i++)
+    {
+      int input;
+      /* each byte conveys four 2-bit move commands */
+      input = dgst_raw[i];
+      for (b = 0; b < 4; b++)
+        {
+          /* evaluate 2 bit, rest is shifted later */
+          x += (input & 0x1) ? 1 : -1;
+          y += (input & 0x2) ? 1 : -1;
+
+          /* assure we are still in bounds */
+          x = MAX (x, 0);
+          y = MAX (y, 0);
+          x = MIN (x, FLDSIZE_X - 1);
+          y = MIN (y, FLDSIZE_Y - 1);
+
+          /* augment the field */
+          if (field[x][y] < len - 2)
+            field[x][y]++;
+          input = input >> 2;
+        }
+    }
+
+  /* mark starting point and end point */
+  field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
+  field[x][y] = len;
+
+  /* fill in retval */
+  snprintf (retval, FLDSIZE_X, "+--[%4s %4u]", key_type, key_size);
+  p = strchr (retval, '\0');
+
+  /* output upper border */
+  for (i = p - retval - 1; i < FLDSIZE_X; i++)
+    *p++ = '-';
+  *p++ = '+';
+  *p++ = '\n';
+
+  /* output content */
+  for (y = 0; y < FLDSIZE_Y; y++)
+    {
+      *p++ = '|';
+      for (x = 0; x < FLDSIZE_X; x++)
+        *p++ = augmentation_string[MIN (field[x][y], len)];
+      *p++ = '|';
+      *p++ = '\n';
+    }
+
+  /* output lower border */
+  *p++ = '+';
+  for (i = 0; i < FLDSIZE_X; i++)
+    *p++ = '-';
+  *p++ = '+';
+
+  return retval;
+}
diff --git a/lib/extras/randomart.h b/lib/extras/randomart.h
new file mode 100644
index 0000000..77d912b
--- /dev/null
+++ b/lib/extras/randomart.h
@@ -0,0 +1,3 @@
+char *
+key_fingerprint_randomart (uint8_t * dgst_raw, u_int dgst_raw_len,
+                           const char *key_type, unsigned int key_size);
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index 75638b9..66d0a9f 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -129,7 +129,7 @@ gnutls_certificate_get_issuer 
(gnutls_certificate_credentials_t sc,
  * sending the names of it would just consume bandwidth without providing 
  * information to client.
  *
- * CA names are used by servers to advertize the CAs they support to
+ * CA names are used by servers to advertise the CAs they support to
  * clients.
  **/
 void
diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c
index c157843..f041821 100644
--- a/lib/gnutls_cipher.c
+++ b/lib/gnutls_cipher.c
@@ -253,7 +253,7 @@ calc_enc_length (gnutls_session_t session, int data_size,
 #define MAX_PREAMBLE_SIZE 16
 
 /* generates the authentication data (data to be hashed only
- * and are not to be send). Returns their size.
+ * and are not to be sent). Returns their size.
  */
 static inline int
 make_preamble (opaque * uint64_data, opaque type, int length,
diff --git a/lib/gnutls_db.c b/lib/gnutls_db.c
index 5e07b04..ed91fe7 100644
--- a/lib/gnutls_db.c
+++ b/lib/gnutls_db.c
@@ -76,8 +76,8 @@ gnutls_db_set_remove_function (gnutls_session_t session,
  * @session: is a #gnutls_session_t structure.
  * @store_func: is the function
  *
- * Sets the function that will be used to store data from the resumed
- * sessions database. This function must remove 0 on success.
+ * Sets the function that will be used to store data in the resumed
+ * sessions database. This function must return 0 on success.
  *
  * The first argument to @store_func will be null unless
  * gnutls_db_set_ptr() has been called.
@@ -124,7 +124,7 @@ gnutls_db_get_ptr (gnutls_session_t session)
  * @seconds: is the number of seconds.
  *
  * Set the expiration time for resumed sessions. The default is 3600
- * (one hour) at the time writing this.
+ * (one hour) at the time of this writing.
  **/
 void
 gnutls_db_set_cache_expiration (gnutls_session_t session, int seconds)
@@ -138,7 +138,7 @@ gnutls_db_set_cache_expiration (gnutls_session_t session, 
int seconds)
  * @session_entry: is the session data (not key)
  *
  * Check if database entry has expired.  This function is to be used
- * when you want to clear unnesessary session which occupy space in
+ * when you want to clear unnecessary sessions which occupy space in
  * your backend.
  *
  * Returns: Returns %GNUTLS_E_EXPIRED, if the database entry has
diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c
index 010e614..e874abb 100644
--- a/lib/gnutls_global.c
+++ b/lib/gnutls_global.c
@@ -130,7 +130,7 @@ gnutls_global_set_log_level (int level)
  * @realloc_func: A realloc function
  * @free_func: The function that frees allocated data. Must accept a NULL 
pointer.
  *
- * This is the function were you set the memory allocation functions
+ * This is the function where you set the memory allocation functions
  * gnutls is going to use. By default the libc's allocation functions
  * (malloc(), free()), are used by gnutls, to allocate both sensitive
  * and not sensitive data.  This function is provided to set the
@@ -184,7 +184,7 @@ static int _gnutls_init = 0;
  * Note that this function will also initialize the underlying crypto
  * backend, if it has not been initialized before.  
  *
- * This function increment a global counter, so that
+ * This function increments a global counter, so that
  * gnutls_global_deinit() only releases resources when it has been
  * called as many times as gnutls_global_init().  This is useful when
  * GnuTLS is used by more than one library in an application.  This
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index bf75919..805bed5 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -2324,7 +2324,7 @@ cleanup:
  *
  * The non-fatal errors such as %GNUTLS_E_AGAIN and
  * %GNUTLS_E_INTERRUPTED interrupt the handshake procedure, which
- * should be later be resumed.  Call this function again, until it
+ * should be resumed later.  Call this function again, until it
  * returns 0; cf.  gnutls_record_get_direction() and
  * gnutls_error_is_fatal().
  *
diff --git a/lib/gnutls_priority.c b/lib/gnutls_priority.c
index 8ac89a5..0a79b67 100644
--- a/lib/gnutls_priority.c
+++ b/lib/gnutls_priority.c
@@ -285,7 +285,7 @@ static const int kx_priority_export[] = {
 
 static const int kx_priority_secure[] = {
   /* The ciphersuites that offer forward secrecy take
-   * precendance
+   * precedence
    */
   GNUTLS_KX_ECDHE_ECDSA,
   GNUTLS_KX_ECDHE_RSA,
@@ -396,7 +396,7 @@ static const int cipher_priority_export[] = {
 };
 
 static const int comp_priority[] = {
-  /* compression should be explicitely requested to be enabled */
+  /* compression should be explicitly requested to be enabled */
   GNUTLS_COMP_NULL,
   0
 };
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index d1b9561..712ba1d 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -725,9 +725,9 @@ gnutls_openpgp_send_cert (gnutls_session_t session,
  *
  * If status is non zero, this function will order gnutls not to send
  * the rdnSequence in the certificate request message. That is the
- * server will not advertize it's trusted CAs to the peer. If status
+ * server will not advertise its trusted CAs to the peer. If status
  * is zero then the default behaviour will take effect, which is to
- * advertize the server's trusted CAs.
+ * advertise the server's trusted CAs.
  *
  * This function has no effect in clients, and in authentication
  * methods other than certificate with X.509 certificates.
diff --git a/lib/gnutls_ui.c b/lib/gnutls_ui.c
index 248c8a0..6205a91 100644
--- a/lib/gnutls_ui.c
+++ b/lib/gnutls_ui.c
@@ -22,7 +22,7 @@
  */
 
 /* This file contains certificate authentication functions to be exported in 
the
- * API and did not fit elsewhere.
+ * API which did not fit elsewhere.
  */
 
 #include <gnutls_int.h>
@@ -34,6 +34,40 @@
 #include <gnutls_auth.h>
 #include <gnutls_state.h>
 #include <gnutls_datum.h>
+#include <extras/randomart.h>
+
+/**
+ * gnutls_random_art:
+ * @type: The type of the random art
+ * @key_type: The type of the key (RSA, DSA etc.)
+ * @key_size: The size of the key in bits
+ * @fpr: The fingerprint of the key
+ * @fpr_size: The size of the fingerprint
+ * @art: The returned random art
+ *
+ * This function will convert a given fingerprint to an "artistic"
+ * image. The returned image is allocated using gnutls_malloc()
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
+ *   an error code is returned.
+ *
+ **/
+int gnutls_random_art (gnutls_random_art_t type, 
+                       const char* key_type, unsigned int key_size,
+                       void * fpr, size_t fpr_size,
+                       gnutls_datum_t* art)
+{
+  if (type != GNUTLS_RANDOM_ART_OPENSSH)
+    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+  art->data = key_fingerprint_randomart(fpr, fpr_size, key_type, key_size);
+  if (art->data == NULL)
+    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+  
+  art->size = strlen(art->data);
+  
+  return 0;
+}
 
 /* ANON & DHE */
 
@@ -42,7 +76,7 @@
  * @session: is a #gnutls_session_t structure.
  * @bits: is the number of bits
  *
- * This function sets the number of bits, for use in an Diffie-Hellman
+ * This function sets the number of bits, for use in a Diffie-Hellman
  * key exchange.  This is used both in DH ephemeral and DH anonymous
  * cipher suites.  This will set the minimum size of the prime that
  * will be used for the handshake.
@@ -313,7 +347,7 @@ mpi_buf2bits (gnutls_datum_t * mpi_buf)
  * This function will return the bits of the prime used in the last
  * Diffie-Hellman key exchange with the peer.  Should be used for both
  * anonymous and ephemeral Diffie-Hellman.  Note that some ciphers,
- * like RSA and DSA without DHE, does not use a Diffie-Hellman key
+ * like RSA and DSA without DHE, do not use a Diffie-Hellman key
  * exchange, and then this function will return 0.
  *
  * Returns: The Diffie-Hellman bit strength is returned, or 0 if no
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index 02821de..84bac69 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -29,6 +29,11 @@
 #include <gnutls/pkcs11.h>
 #include <gnutls/openpgp.h>
 
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
 /* Public key operations */
 
 struct gnutls_pubkey_st;
@@ -280,4 +285,8 @@ gnutls_certificate_set_key 
(gnutls_certificate_credentials_t res,
                             int pcert_list_size,
                             gnutls_privkey_t key);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 2906eaa..3080dd0 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -1268,13 +1268,21 @@ gnutls_ecc_curve_t 
gnutls_ecc_curve_get(gnutls_session_t session);
   void gnutls_openpgp_send_cert (gnutls_session_t session,
                                  gnutls_openpgp_crt_status_t status);
 
-/* fingerprint 
- * Actually this function returns the hash of the given data.
+/* This function returns the hash of the given data.
  */
   int gnutls_fingerprint (gnutls_digest_algorithm_t algo,
                           const gnutls_datum_t * data, void *result,
                           size_t * result_size);
 
+  typedef enum gnutls_random_art
+  {
+    GNUTLS_RANDOM_ART_OPENSSH=1,
+  } gnutls_random_art_t;
+
+  int gnutls_random_art (gnutls_random_art_t type, 
+                         const char* key_name, unsigned int key_size,
+                         void * fpr, size_t fpr_size,
+                         gnutls_datum_t* art);
 
 /* SRP 
  */
diff --git a/lib/includes/gnutls/pkcs11.h b/lib/includes/gnutls/pkcs11.h
index 31fa551..14576f2 100644
--- a/lib/includes/gnutls/pkcs11.h
+++ b/lib/includes/gnutls/pkcs11.h
@@ -28,6 +28,11 @@
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
 
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
 #define GNUTLS_PKCS11_MAX_PIN_LEN 32
 
 /**
@@ -343,4 +348,8 @@ gnutls_pkcs11_privkey_generate (const char* url,
   gnutls_pk_algorithm_t pk, unsigned int bits, 
   const char* label, unsigned int flags);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 24f04f0..0477210 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -726,6 +726,7 @@ GNUTLS_3_0_0 {
        gnutls_srp_4096_group_prime;
        gnutls_x509_privkey_verify_params;
        gnutls_priority_get_cipher_suite_index;
+       gnutls_random_art;
 } GNUTLS_2_12;
 
 GNUTLS_PRIVATE {
diff --git a/lib/nettle/rnd.c b/lib/nettle/rnd.c
index 3f611f1..792d65c 100644
--- a/lib/nettle/rnd.c
+++ b/lib/nettle/rnd.c
@@ -116,7 +116,7 @@ do_device_source (int init)
       && (init || ((now - device_last_read) > DEVICE_READ_INTERVAL)))
     {
 
-      /* More than a minute since we last read the device */
+      /* More than 20 minutes since we last read the device */
       uint8_t buf[DEVICE_READ_SIZE_MAX];
 
       if (!CryptGenRandom (device_fd, (DWORD) read_size, buf))
@@ -250,7 +250,7 @@ do_device_source_urandom (int init)
   if ((device_fd > 0)
       && (init || ((now - device_last_read) > DEVICE_READ_INTERVAL)))
     {
-      /* More than a minute since we last read the device */
+      /* More than 20 minutes since we last read the device */
       uint8_t buf[DEVICE_READ_SIZE_MAX];
       uint32_t done;
 
@@ -312,7 +312,7 @@ do_device_source_egd (int init)
       && (init || ((now - device_last_read) > DEVICE_READ_INTERVAL)))
     {
 
-      /* More than a minute since we last read the device */
+      /* More than 20 minutes since we last read the device */
       uint8_t buf[DEVICE_READ_SIZE_MAX];
       uint32_t done;
 
diff --git a/lib/openpgp/output.c b/lib/openpgp/output.c
index 2b5f12d..defcf95 100644
--- a/lib/openpgp/output.c
+++ b/lib/openpgp/output.c
@@ -26,6 +26,7 @@
 #include <gnutls_int.h>
 #include <gnutls/openpgp.h>
 #include <gnutls_errors.h>
+#include <extras/randomart.h>
 
 /* I18n of error codes. */
 #include "gettext.h"
@@ -88,6 +89,7 @@ print_key_id (gnutls_buffer_st * str, gnutls_openpgp_crt_t 
cert, int idx)
       _gnutls_buffer_hexprint (str, id, sizeof (id));
       addf (str, "\n");
     }
+
 }
 
 /* idx == -1 indicates main key
@@ -99,6 +101,9 @@ print_key_fingerprint (gnutls_buffer_st * str, 
gnutls_openpgp_crt_t cert)
   char fpr[128];
   size_t fpr_size = sizeof (fpr);
   int err;
+  const char* name;
+  char* p;
+  unsigned int bits;
 
   err = gnutls_openpgp_crt_get_fingerprint (cert, fpr, &fpr_size);
   if (err < 0)
@@ -109,6 +114,24 @@ print_key_fingerprint (gnutls_buffer_st * str, 
gnutls_openpgp_crt_t cert)
       _gnutls_buffer_hexprint (str, fpr, fpr_size);
       addf (str, "\n");
     }
+
+  err = gnutls_openpgp_crt_get_pk_algorithm (cert, &bits);
+  if (err < 0)
+    return;
+    
+  name = gnutls_pk_get_name(err);
+  if (name == NULL)
+    return;
+
+  p = key_fingerprint_randomart(fpr, fpr_size, name, bits);
+  if (p == NULL)
+    return;
+  
+  adds (str, _("\trandomart:\n"));
+  adds (str, p);
+  adds (str, "\n");
+
+  gnutls_free(p);
 }
 
 static void
diff --git a/lib/system.c b/lib/system.c
index 88468d6..e5440fe 100644
--- a/lib/system.c
+++ b/lib/system.c
@@ -185,14 +185,6 @@ gnutls_system_mutex_unlock (void **priv)
   return 0;
 }
 
-int
-_gnutls_atfork (void (*prepare) (void), void (*parent) (void),
-                void (*child) (void))
-{
-  return 0;
-}
-
-
 #endif /* WIN32_LOCKS */
 
 #ifdef HAVE_PTHREAD_LOCKS
@@ -251,13 +243,6 @@ gnutls_system_mutex_unlock (void **priv)
   return 0;
 }
 
-int
-_gnutls_atfork (void (*prepare) (void), void (*parent) (void),
-                void (*child) (void))
-{
-  return pthread_atfork (prepare, parent, child);
-}
-
 #endif /* PTHREAD_LOCKS */
 
 #ifdef HAVE_NO_LOCKS
@@ -286,13 +271,6 @@ gnutls_system_mutex_unlock (void **priv)
   return 0;
 }
 
-int
-_gnutls_atfork (void (*prepare) (void), void (*parent) (void),
-                void (*child) (void))
-{
-  return 0;
-}
-
 #endif /* NO_LOCKS */
 
 gnutls_time_func gnutls_time = time;
diff --git a/lib/system.h b/lib/system.h
index 7029c9c..e3b47b8 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -34,8 +34,6 @@ ssize_t system_read_peek (gnutls_transport_ptr_t ptr, void 
*data,
 #endif
 #endif
 
-int _gnutls_atfork (void (*prepare) (void), void (*parent) (void),
-                    void (*child) (void));
 extern gnutls_time_func gnutls_time;
 
 static inline void millisleep(unsigned int ms)
diff --git a/lib/x509/output.c b/lib/x509/output.c
index b0e8640..204c7bd 100644
--- a/lib/x509/output.c
+++ b/lib/x509/output.c
@@ -29,6 +29,7 @@
 #include <x509_int.h>
 #include <gnutls_num.h>
 #include <gnutls_errors.h>
+#include <extras/randomart.h>
 
 /* I18n of error codes. */
 #include "gettext.h"
@@ -1348,7 +1349,10 @@ print_fingerprint (gnutls_buffer_st * str, 
gnutls_x509_crt_t cert,
   int err;
   char buffer[MAX_HASH_SIZE];
   size_t size = sizeof (buffer);
-
+  const char* name;
+  char* p;
+  unsigned int bits;
+  
   err = gnutls_x509_crt_get_fingerprint (cert, algo, buffer, &size);
   if (err < 0)
     {
@@ -1362,6 +1366,24 @@ print_fingerprint (gnutls_buffer_st * str, 
gnutls_x509_crt_t cert,
     adds (str, _("\tSHA-1 fingerprint:\n\t\t"));
   _gnutls_buffer_hexprint (str, buffer, size);
   adds (str, "\n");
+
+  err = gnutls_x509_crt_get_pk_algorithm (cert, &bits);
+  if (err < 0)
+    return;
+    
+  name = gnutls_pk_get_name(err);
+  if (name == NULL)
+    return;
+
+  p = key_fingerprint_randomart(buffer, size, name, bits);
+  if (p == NULL)
+    return;
+  
+  adds (str, _("\trandomart:\n"));
+  adds (str, p);
+  adds (str, "\n\n");
+
+  gnutls_free(p);
 }
 
 static void
@@ -1388,7 +1410,6 @@ print_other (gnutls_buffer_st * str, gnutls_x509_crt_t 
cert, int notsigned)
 {
   if (!notsigned)
     {
-      print_fingerprint (str, cert, GNUTLS_DIG_MD5);
       print_fingerprint (str, cert, GNUTLS_DIG_SHA1);
     }
   print_keyid (str, cert);
diff --git a/src/cli.c b/src/cli.c
index 946dc85..8676d1c 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -1460,17 +1460,20 @@ socket_open (socket_st * hd, const char *hostname, 
const char *service)
       exit (1);
     }
 
-#ifdef IP_DONTFRAG
   if (hints.ai_socktype == SOCK_DGRAM)
     {
+#if defined(IP_DONTFRAG)
       int yes = 1;
       if (setsockopt (sd, IPPROTO_IP, IP_DONTFRAG,
-                          (const void *) &yes, sizeof (yes)) < 0)
-        {
-          perror ("setsockopt(IP_DF) failed");
-        }
-    }
+                      (const void *) &yes, sizeof (yes)) < 0)
+        perror ("setsockopt(IP_DF) failed");
+#elif defined(IP_MTU_DISCOVER)
+      int yes = IP_PMTUDISC_DO;
+      if (setsockopt(sd, IPPROTO_IP, IP_MTU_DISCOVER, 
+                     (const void*) &yes, sizeof (yes)) < 0)
+        perror ("setsockopt(IP_DF) failed");
 #endif
+    }
 
   hd->secure = 0;
   hd->fd = sd;
diff --git a/src/serv.c b/src/serv.c
index 8959d7f..370a669 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -733,18 +733,21 @@ listen_socket (const char *name, int listen_port, int 
socktype)
               continue;
             }
         }
-#ifdef IP_DONTFRAG
       else
         {
+#if defined(IP_DONTFRAG)
           yes = 1;
           if (setsockopt (s, IPPROTO_IP, IP_DONTFRAG,
                           (const void *) &yes, sizeof (yes)) < 0)
-            {
               perror ("setsockopt(IP_DF) failed");
-            }
-        }
+#elif defined(IP_MTU_DISCOVER)
+          yes = IP_PMTUDISC_DO;
+          if (setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, 
+                         (const void*) &yes, sizeof (yes)) < 0)
+              perror ("setsockopt(IP_DF) failed");
 #endif
-      
+        }
+
       if (bind (s, ptr->ai_addr, ptr->ai_addrlen) < 0)
         {
           perror ("bind() failed");
@@ -916,13 +919,17 @@ main (int argc, char **argv)
   if (nodb == 0)
     wrap_db_init ();
 
+  if (info.udp != 0)
+    strcpy(name, "UDP ");
+  else name[0] = 0;
+
   if (http == 1)
     {
-      strcpy (name, "HTTP Server");
+      strcat (name, "HTTP Server");
     }
   else
     {
-      strcpy (name, "Echo Server");
+      strcat (name, "Echo Server");
     }
 
   gnutls_global_set_log_function (tls_log_func);
diff --git a/src/udp-serv.c b/src/udp-serv.c
index b41b1ea..2d98f45 100644
--- a/src/udp-serv.c
+++ b/src/udp-serv.c
@@ -138,6 +138,7 @@ int udp_server(const char* name, int port, int mtu)
         if (ret < 0)
           {
             fprintf(stderr, "Error in handshake(): %s\n", 
gnutls_strerror(ret));
+            gnutls_deinit(session);
             continue;
           }
 


hooks/post-receive
-- 
GNU gnutls



reply via email to

[Prev in Thread] Current Thread [Next in Thread]