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_12-191-g94474c4


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls-3_0_12-191-g94474c4
Date: Fri, 10 Feb 2012 13:15:42 +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=94474c4e8ee2888c1b90acd49132eba50c7d2b27

The branch, master has been updated
       via  94474c4e8ee2888c1b90acd49132eba50c7d2b27 (commit)
       via  2cfe70557d8acea4e8579401697aed5fc5fe2618 (commit)
       via  e9c7622a1e2182402574fb5f929798cafc8c1a98 (commit)
       via  fd44edbec06a855845abdc5c17ccc5cd89a10066 (commit)
       via  54d0523bed22fbd48e709c0bd24146b0519748fe (commit)
       via  3ab7ba3e58bce695df7bbb72afeb51f947a18475 (commit)
       via  4143ace26a4ce0810d373f1f3ff28a2cdf9786f7 (commit)
       via  3ccc4cf605dcb2007305aa44bb9d0241b31e74f4 (commit)
       via  897bfb3db9ba20a87ba84c23301f2ab605c35f48 (commit)
       via  8b98440c8b00f354e500aeb88099c3e8dd59cf92 (commit)
       via  fc8c253957a8f642cee1c263c742cc96f966c01c (commit)
       via  0c80380095f77d732fbd126f05a0a03fa3cc3458 (commit)
       via  78f921261af3a1cbf79b5ad41c82d332968e2d89 (commit)
       via  aac639e82dd773b9f1079d92156d3dfc99d5f08f (commit)
       via  5196d292991628627e4ef7cc977b84f1273fe233 (commit)
       via  38f9998e9aaee0e8a486cad3f715fad4558a88df (commit)
       via  a2768dd44037e594ca1b52c0261bad4b88a857ee (commit)
       via  cfab8fce9c36a4e350b3dfc31b450e9b44039eae (commit)
       via  ec3a7d2279500b03b9fd7a46eca469e7073457dd (commit)
       via  309f04b111bcb507f6abed9669185fe1de66787f (commit)
       via  2fe123a63342125ac101df5ce5ab978dc5e3ed36 (commit)
      from  a64a322efe490dd63bbdd200223fbf109a74d003 (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 94474c4e8ee2888c1b90acd49132eba50c7d2b27
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 14:20:49 2012 +0100

    updated NEWS

commit 2cfe70557d8acea4e8579401697aed5fc5fe2618
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 14:13:04 2012 +0100

    added missing files

commit e9c7622a1e2182402574fb5f929798cafc8c1a98
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 14:07:51 2012 +0100

    resolve port only when needed to.

commit fd44edbec06a855845abdc5c17ccc5cd89a10066
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 14:02:34 2012 +0100

    updated makefile

commit 54d0523bed22fbd48e709c0bd24146b0519748fe
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 14:02:15 2012 +0100

    fix in non-blocking case.

commit 3ab7ba3e58bce695df7bbb72afeb51f947a18475
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 13:42:50 2012 +0100

    small correction

commit 4143ace26a4ce0810d373f1f3ff28a2cdf9786f7
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 13:42:37 2012 +0100

    corrected subdirs for libopts

commit 3ccc4cf605dcb2007305aa44bb9d0241b31e74f4
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 13:39:11 2012 +0100

    ENABLE_PKI is no more

commit 897bfb3db9ba20a87ba84c23301f2ab605c35f48
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 13:28:13 2012 +0100

    fix

commit 8b98440c8b00f354e500aeb88099c3e8dd59cf92
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 13:25:47 2012 +0100

    fix compilation

commit fc8c253957a8f642cee1c263c742cc96f966c01c
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 13:25:39 2012 +0100

    fixed leak

commit 0c80380095f77d732fbd126f05a0a03fa3cc3458
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 13:25:24 2012 +0100

    cleanup enable/disable options stuff.

commit 78f921261af3a1cbf79b5ad41c82d332968e2d89
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 13:17:32 2012 +0100

    fixes to allow libopts to compile in windows

commit aac639e82dd773b9f1079d92156d3dfc99d5f08f
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 12:53:51 2012 +0100

    corrected typo

commit 5196d292991628627e4ef7cc977b84f1273fe233
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 12:30:23 2012 +0100

    gnutls_verify_stored_pubkey() and gnutls_store_pubkey() allow for 
alternative storage back-end.

commit 38f9998e9aaee0e8a486cad3f715fad4558a88df
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 11:11:02 2012 +0100

    use getservbyport() to obtain the service name.

commit a2768dd44037e594ca1b52c0261bad4b88a857ee
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 11:09:08 2012 +0100

    added servent

commit cfab8fce9c36a4e350b3dfc31b450e9b44039eae
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 10:44:21 2012 +0100

    use updated api

commit ec3a7d2279500b03b9fd7a46eca469e7073457dd
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 10:37:54 2012 +0100

    updated for new eagain-common.h

commit 309f04b111bcb507f6abed9669185fe1de66787f
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 10:35:29 2012 +0100

    Removed the application field and added an expiration field.

commit 2fe123a63342125ac101df5ce5ab978dc5e3ed36
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Feb 10 10:27:10 2012 +0100

    updated example

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

Summary of changes:
 Makefile.am                     |    4 -
 NEWS                            |    4 +-
 configure.ac                    |   31 +++++++--
 cross.mk                        |    8 +-
 doc/cha-cert-auth.texi          |   13 ++--
 doc/cha-gtls-examples.texi      |    5 +-
 doc/examples/Makefile.am        |    9 +--
 doc/examples/ex-client-x509.c   |    9 ++-
 doc/examples/ex-verify-ssh.c    |    7 ++-
 gl/Makefile.am                  |    2 +-
 gl/m4/gnulib-cache.m4           |    3 +-
 lib/gnutls_dtls.c               |   29 +++++---
 lib/gnutls_x509.c               |    8 --
 lib/includes/gnutls/gnutls.h.in |   35 ++++++++--
 lib/system.c                    |    2 +-
 lib/verify-ssh.c                |  138 ++++++++++++++++++++++++++-------------
 lib/x509/crl.c                  |    3 -
 lib/x509/crl_write.c            |    3 -
 lib/x509/crq.c                  |    4 -
 lib/x509/extensions.c           |    3 -
 lib/x509/mpi.c                  |    5 --
 lib/x509/output.c               |   15 ----
 lib/x509/pkcs12.c               |    4 -
 lib/x509/pkcs12_bag.c           |    5 --
 lib/x509/pkcs12_encr.c          |    3 -
 lib/x509/pkcs7.c                |    5 +-
 lib/x509/privkey.c              |    4 -
 lib/x509/privkey_pkcs8.c        |    4 -
 lib/x509/sign.c                 |    3 -
 lib/x509/verify.c               |    7 --
 lib/x509/x509.c                 |    3 -
 lib/x509/x509_write.c           |    5 --
 m4/hooks.m4                     |   23 ++-----
 src/Makefile.am                 |   13 ++--
 src/benchmark-tls.c             |    4 +-
 src/cli-args.def                |    6 +-
 src/cli.c                       |   42 ++++++++++--
 src/dh.c                        |    3 -
 src/libopts/compat/compat.h     |    4 +-
 src/libopts/cook.c              |    4 +-
 src/libopts/makeshell.c         |    2 +
 src/libopts/text_mmap.c         |    2 +-
 src/serv.c                      |    2 -
 src/socket.c                    |   27 +-------
 src/socket.h                    |    1 -
 45 files changed, 264 insertions(+), 252 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 4fdae71..6be58fe 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,10 +23,6 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc 
--disable-valgrind-tests
 
 SUBDIRS = gl lib extra po
 
-if NEED_LIBOPTS
-SUBDIRS += $(LIBOPTS_DIR)
-endif
-
 SUBDIRS += src doc tests
 
 if HAVE_GUILE
diff --git a/NEWS b/NEWS
index 7dd91df..ec461be 100644
--- a/NEWS
+++ b/NEWS
@@ -7,7 +7,7 @@ See the end for copying conditions.
 ** gnutls-cli: added the --ocsp option which will verify
 the peer's certificate with OCSP.
 
-** gnutls-cli: added the --ssh and if specified, gnutls-cli
+** gnutls-cli: added the --tofu and if specified, gnutls-cli
 will use an ssh-style authentication method.
 
 ** gnutls-cli: if no --x509cafile is provided a default is
@@ -26,7 +26,7 @@ the last flight.
 Report and patch by Sean Buckheister.
 
 ** libgnutls: Added new functions to easily allow the usage of
-an SSH-style authentication.
+a trust on first use (SSH-style) authentication.
 
 ** libgnutls: SUITEB128 and SUITEB192 priority strings account
 for the RFC6460 requirements.
diff --git a/configure.ac b/configure.ac
index b992f35..78caaf5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure 
script.
 # USA
 
 AC_PREREQ(2.61)
-AC_INIT([GnuTLS], [3.0.12], address@hidden)
+AC_INIT([GnuTLS], [3.0.13], address@hidden)
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_MACRO_DIR([m4])
 
@@ -118,7 +118,7 @@ AC_C_BIGENDIAN
 
 
 dnl No fork on MinGW, disable some self-tests until we fix them.
-AC_CHECK_FUNCS([fork getrusage getpwuid_r daemon],,)
+AC_CHECK_FUNCS([fork getrusage getpwuid_r daemon fchmod],,)
 AM_CONDITIONAL(HAVE_FORK, test "$ac_cv_func_fork" != "no")
 AC_LIB_HAVE_LINKFLAGS(pthread,, [#include <pthread.h>], [pthread_mutex_lock 
(0);])
 
@@ -484,13 +484,34 @@ AC_MSG_NOTICE([summary of build options:
   Warning flags:    errors: ${WERROR_CFLAGS} warnings: ${WARN_CFLAGS}
   Library types:    Shared=${enable_shared}, Static=${enable_static}
   Valgrind:         $opt_valgrind_tests ${VALGRIND}
+])
+
+AC_MSG_NOTICE([Optional features:
+(note that included applications might not compile properly
+if features are disabled)
+
+  OCSP support:     $ac_enable_ocsp
+  OpenPGP support:  $ac_enable_openpgp
+  SRP support:      $ac_enable_srp
+  PSK support:      $ac_enable_psk
+  Anon auth support:$ac_enable_anon
+])
+
+AC_MSG_NOTICE([Optional applications:
+
+  crywrap app:      $libidn
+])
+
+AC_MSG_NOTICE([Optional libraries:
+
   Guile wrappers:   $opt_guile_bindings
   C++ library:      $use_cxx
   OpenSSL compat:   $enable_openssl
+])
+
+AC_MSG_NOTICE([Hardware acceleration/support:
+
   /dev/crypto:      $enable_cryptodev
   Hardware accel:   $hw_accel
-  Crypto library:   $cryptolib
   PKCS#11 support:  $with_p11_kit
-  crywrap app:      $libidn
-  OCSP support:     $ac_enable_ocsp
 ])
diff --git a/cross.mk b/cross.mk
index 2d80989..7bbd67f 100644
--- a/cross.mk
+++ b/cross.mk
@@ -1,6 +1,6 @@
 
-GNUTLS_FILE:=gnutls-3.0.11.tar.xz
-GNUTLS_DIR:=gnutls-3.0.11
+GNUTLS_FILE:=gnutls-3.0.13.tar.xz
+GNUTLS_DIR:=gnutls-3.0.13
 
 GMP_FILE:=gmp-5.0.2.tar.bz2
 GMP_DIR:=gmp-5.0.2
@@ -39,7 +39,7 @@ $(LIB_DIR):
        mkdir -p $(LIB_DIR)
        mkdir -p $(HEADERS_DIR)
 
-CONFIG_FLAGS := --host=i686-w64-mingw32 --enable-shared --disable-static 
--bindir=$(BIN_DIR) --libdir=$(LIB_DIR) --includedir=$(HEADERS_DIR)
+CONFIG_FLAGS := --prefix=$(CROSS_DIR) --host=i686-w64-mingw32 --enable-shared 
--disable-static --bindir=$(BIN_DIR) --libdir=$(LIB_DIR) 
--includedir=$(HEADERS_DIR)
 
 $(P11_KIT_DIR)/.configured:
        test -f $(P11_KIT_FILE) || wget 
http://p11-glue.freedesktop.org/releases/$(P11_KIT_FILE)
@@ -103,7 +103,7 @@ $(GNUTLS_DIR)/.configured: $(NETTLE_DIR)/.installed 
$(P11_KIT_DIR)/.installed
                P11_KIT_CFLAGS="-I$(HEADERS_DIR)" \
                P11_KIT_LIBS="$(LIB_DIR)/libp11-kit.la" \
                LDFLAGS="-L$(LIB_DIR)" CFLAGS="-I$(HEADERS_DIR)" 
CXXFLAGS="-I$(HEADERS_DIR)" \
-               ./configure $(CONFIG_FLAGS) --with-libnettle-prefix=$(LIB_DIR) \
+               ./configure $(CONFIG_FLAGS) --enable-local-libopts 
--with-libnettle-prefix=$(LIB_DIR) \
                --disable-openssl-compatibility && cd ..
        touch $@
 
diff --git a/doc/cha-cert-auth.texi b/doc/cha-cert-auth.texi
index 7fb41a6..a2656ad 100644
--- a/doc/cha-cert-auth.texi
+++ b/doc/cha-cert-auth.texi
@@ -87,7 +87,7 @@ acceptable.  The framework is illustrated on @ref{fig:x509}.
 * X.509 distinguished names::
 * Verifying X.509 certificate paths::
 * Verifying a certificate in the context of TLS session::
-* Verifying a certificate using SSH-style authentication::
+* Verifying a certificate using trust on first use authentication::
 @end menu
 
 @node X.509 certificate structure
@@ -277,15 +277,16 @@ about the peer's identity. It is required to verify if the
 certificate's owner is the one you expect. For more information
 consult @xcite{RFC2818} and section @ref{ex:verify} for an example.
 
address@hidden Verifying a certificate using SSH-style authentication
address@hidden Verifying a certificate using SSH-style authentication
address@hidden Verifying a certificate using trust on first use authentication
address@hidden Verifying a certificate using trust on first use authentication
 @cindex verifying certificate paths
 @cindex SSH-style authentication
address@hidden Trust on first use
 @tindex gnutls_certificate_verify_flags
 
-It is possible to use an SSH-style authentication method in GnuTLS.
-That means that having seen and associated a public key with a host
-is enough to trust it on the subsequent connections.
+It is possible to use a trust on first use (similar to SSH) authentication 
+method in GnuTLS. That means that having seen and associated a public key 
+with a host is enough to trust it on the subsequent connections.
 A hybrid system with X.509 and SSH authentication is 
 shown in @ref{Simple client example with SSH-style certificate verification}.
 
diff --git a/doc/cha-gtls-examples.texi b/doc/cha-gtls-examples.texi
index 9d253a0..637653c 100644
--- a/doc/cha-gtls-examples.texi
+++ b/doc/cha-gtls-examples.texi
@@ -70,8 +70,9 @@ resumption.
 
 This is an alternative verification function that will use the
 X.509 certificate authorities for verification, but also assume an
-SSH-like authentication system. That is the user is prompted on unknown 
-public keys and known public keys are considered trusted.
+trust on first use (SSH-like) authentication system. That is the user is 
+prompted on unknown public keys and known public keys are considered 
+trusted.
 
 @verbatiminclude examples/ex-verify-ssh.c
 
diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am
index ed1592c..29f612f 100644
--- a/doc/examples/Makefile.am
+++ b/doc/examples/Makefile.am
@@ -43,10 +43,6 @@ CXX_LDADD = $(LDADD) \
 noinst_PROGRAMS = ex-client-resume ex-client-dtls
 noinst_PROGRAMS += ex-cert-select ex-client-x509
 
-if ENABLE_PKI
-noinst_PROGRAMS += print-ciphersuites ex-crq ex-serv-x509 ex-serv-dtls
-endif
-
 if ENABLE_CXX
 ex_cxx_SOURCES = ex-cxx.cpp
 ex_cxx_LDADD = $(CXX_LDADD)
@@ -67,10 +63,8 @@ endif
 
 if ENABLE_PSK
 noinst_PROGRAMS += ex-client-psk
-if ENABLE_PKI
 noinst_PROGRAMS += ex-serv-psk
 endif
-endif
 
 if ENABLE_SRP
 noinst_PROGRAMS += ex-client-srp ex-serv-srp
@@ -84,4 +78,5 @@ endif
 
 libexamples_la_SOURCES = examples.h ex-alert.c ex-pkcs12.c \
        ex-session-info.c ex-x509-info.c ex-verify.c    \
-       tcp.c udp.c ex-pkcs11-list.c verify.c ex-verify-ssh.c
+       tcp.c udp.c ex-pkcs11-list.c verify.c ex-verify-ssh.c \
+       ex-serv-dtls.c print-ciphersuites.c
diff --git a/doc/examples/ex-client-x509.c b/doc/examples/ex-client-x509.c
index c5ed190..ab46118 100644
--- a/doc/examples/ex-client-x509.c
+++ b/doc/examples/ex-client-x509.c
@@ -12,7 +12,8 @@
 #include "examples.h"
 
 /* A very basic TLS client, with X.509 authentication and server certificate
- * verification.
+ * verification. Note that error checking for missing files etc. is missing
+ * for simplicity.
  */
 
 #define MAX_BUF 1024
@@ -79,7 +80,11 @@ int main (void)
 
   /* Perform the TLS handshake
    */
-  ret = gnutls_handshake (session);
+  do
+    {
+      ret = gnutls_handshake (session);
+    }
+  while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
 
   if (ret < 0)
     {
diff --git a/doc/examples/ex-verify-ssh.c b/doc/examples/ex-verify-ssh.c
index c9a66b2..dd983ce 100644
--- a/doc/examples/ex-verify-ssh.c
+++ b/doc/examples/ex-verify-ssh.c
@@ -92,7 +92,8 @@ _ssh_verify_certificate_callback (gnutls_session_t session)
 
   gnutls_x509_crt_deinit (cert);
   
-  ret = gnutls_verify_stored_pubkey(NULL, NULL, hostname, "443", 
+  /* service may be obtained alternatively using getservbyport() */
+  ret = gnutls_verify_stored_pubkey(NULL, NULL, hostname, "https", 
                                     GNUTLS_CRT_X509, &cert_list[0], 0);
   if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
     {
@@ -128,7 +129,9 @@ _ssh_verify_certificate_callback (gnutls_session_t session)
   /* user trusts the key -> store it */
   if (ret != 0)
     {
-      ret = gnutls_store_pubkey(NULL, NULL, hostname, "443", GNUTLS_CRT_X509, 
&cert_list[0], 0);
+      ret = gnutls_store_pubkey(NULL, NULL, hostname, "https", 
+                                GNUTLS_CRT_X509, &cert_list[0], 
+                                0, 0);
       if (ret < 0)
         fprintf(stderr, "gnutls_store_pubkey: %s\n", gnutls_strerror(ret));
     }
diff --git a/gl/Makefile.am b/gl/Makefile.am
index e21e585..98064a9 100644
--- a/gl/Makefile.am
+++ b/gl/Makefile.am
@@ -21,7 +21,7 @@
 # the same distribution terms as the rest of that program.
 #
 # Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --dir=. --local-dir=gl/override 
--lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc 
--tests-base=gl/tests --aux-dir=build-aux --with-tests --avoid=alignof-tests 
--avoid=lock-tests --avoid=lseek-tests --no-conditional-dependencies --libtool 
--macro-prefix=gl --no-vc-files accept alloca alphasort argp base64 bind 
byteswap c-ctype close connect error extensions func gendocs getaddrinfo 
getpass getsubopt gettext gettime havelib inet_ntop inet_pton lib-msvc-compat 
lib-symbol-versions listen maintainer-makefile manywarnings memmem-simple 
minmax netdb netinet_in pmccabe2html progname read-file recv recvfrom scandir 
select send sendto setsockopt shutdown snprintf socket sockets socklen stdint 
strcase strndup strtok_r strverscmp sys_socket sys_stat time_r timespec u64 
unistd valgrind-tests vasprintf version-etc version-etc-fsf vfprintf-posix 
vprintf-posix vsnprintf warnings
+# Reproduce by: gnulib-tool --import --dir=. --local-dir=gl/override 
--lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc 
--tests-base=gl/tests --aux-dir=build-aux --with-tests --avoid=alignof-tests 
--avoid=lock-tests --avoid=lseek-tests --no-conditional-dependencies --libtool 
--macro-prefix=gl --no-vc-files accept alloca alphasort argp base64 bind 
byteswap c-ctype close connect error extensions func gendocs getaddrinfo 
getpass getsubopt gettext gettime havelib inet_ntop inet_pton lib-msvc-compat 
lib-symbol-versions listen maintainer-makefile manywarnings memmem-simple 
minmax netdb netinet_in pmccabe2html progname read-file recv recvfrom scandir 
select send sendto servent setsockopt shutdown snprintf socket sockets socklen 
stdint strcase strndup strtok_r strverscmp sys_socket sys_stat time_r timespec 
u64 unistd valgrind-tests vasprintf version-etc version-etc-fsf vfprintf-posix 
vprintf-posix vsnprintf warnings
 
 AUTOMAKE_OPTIONS = 1.5 gnits
 
diff --git a/gl/m4/gnulib-cache.m4 b/gl/m4/gnulib-cache.m4
index 0e41084..1ab5841 100644
--- a/gl/m4/gnulib-cache.m4
+++ b/gl/m4/gnulib-cache.m4
@@ -27,7 +27,7 @@
 
 
 # Specification in the form of a command-line invocation:
-#   gnulib-tool --import --dir=. --local-dir=gl/override --lib=libgnu 
--source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests 
--aux-dir=build-aux --with-tests --avoid=alignof-tests --avoid=lock-tests 
--avoid=lseek-tests --no-conditional-dependencies --libtool --macro-prefix=gl 
--no-vc-files accept alloca alphasort argp base64 bind byteswap c-ctype close 
connect error extensions func gendocs getaddrinfo getpass getsubopt gettext 
gettime havelib inet_ntop inet_pton lib-msvc-compat lib-symbol-versions listen 
maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in 
pmccabe2html progname read-file recv recvfrom scandir select send sendto 
setsockopt shutdown snprintf socket sockets socklen stdint strcase strndup 
strtok_r strverscmp sys_socket sys_stat time_r timespec u64 unistd 
valgrind-tests vasprintf version-etc version-etc-fsf vfprintf-posix 
vprintf-posix vsnprintf warnings
+#   gnulib-tool --import --dir=. --local-dir=gl/override --lib=libgnu 
--source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests 
--aux-dir=build-aux --with-tests --avoid=alignof-tests --avoid=lock-tests 
--avoid=lseek-tests --no-conditional-dependencies --libtool --macro-prefix=gl 
--no-vc-files accept alloca alphasort argp base64 bind byteswap c-ctype close 
connect error extensions func gendocs getaddrinfo getpass getsubopt gettext 
gettime havelib inet_ntop inet_pton lib-msvc-compat lib-symbol-versions listen 
maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in 
pmccabe2html progname read-file recv recvfrom scandir select send sendto 
servent setsockopt shutdown snprintf socket sockets socklen stdint strcase 
strndup strtok_r strverscmp sys_socket sys_stat time_r timespec u64 unistd 
valgrind-tests vasprintf version-etc version-etc-fsf vfprintf-posix 
vprintf-posix vsnprintf warnings
 
 # Specification in the form of a few gnulib-tool.m4 macro invocations:
 gl_LOCAL_DIR([gl/override])
@@ -72,6 +72,7 @@ gl_MODULES([
   select
   send
   sendto
+  servent
   setsockopt
   shutdown
   snprintf
diff --git a/lib/gnutls_dtls.c b/lib/gnutls_dtls.c
index 6669064..1dd3ccb 100644
--- a/lib/gnutls_dtls.c
+++ b/lib/gnutls_dtls.c
@@ -62,7 +62,7 @@ transmit_message (gnutls_session_t session,
         _mbuffer_get_uhead_size(bufel), 0);
     }
 
-  *buf = gnutls_realloc_fast(*buf, mtu + DTLS_HANDSHAKE_HEADER_SIZE);
+  if (*buf == NULL) *buf = gnutls_malloc(mtu + DTLS_HANDSHAKE_HEADER_SIZE);
   if (*buf == NULL)
     return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
 
@@ -211,15 +211,18 @@ unsigned int timeout;
                   session->internals.dtls.actual_retrans_timeout_ms)
                 {
                   session->internals.dtls.handshake_last_call = now;
+                  gnutls_assert();
                   goto nb_timeout;
                 }
             }
           else /* received ack */
             {
               ret = 0;
-              goto cleanup;
+              goto end_flight;
             }
         }
+      else /* last flight of an async party. Return immediately. */
+        return ret;
     }
 
   do 
@@ -227,7 +230,7 @@ unsigned int timeout;
       if (1000*(now-session->internals.dtls.handshake_start_time) >= 
session->internals.dtls.total_timeout_ms) 
         {
           ret = gnutls_assert_val(GNUTLS_E_TIMEDOUT);
-          goto cleanup;
+          goto end_flight;
         }
 
       _gnutls_dtls_log ("DTLS[%p]: %sStart of flight transmission.\n", 
session,  (session->internals.dtls.flight_init == 0)?"":"re-");
@@ -239,7 +242,7 @@ unsigned int timeout;
           if (ret < 0)
             {
               gnutls_assert();
-              goto cleanup;
+              goto end_flight;
             }
 
           last_type = cur->htype;
@@ -271,7 +274,10 @@ unsigned int timeout;
 
       ret = _gnutls_io_write_flush (session);
       if (ret < 0)
-        return gnutls_assert_val(ret);
+        {
+          ret = gnutls_assert_val(ret);
+          goto cleanup;
+        }
 
       /* last message in handshake -> no ack */
       if (session->internals.dtls.last_flight != 0)
@@ -281,7 +287,8 @@ unsigned int timeout;
            * we rely on the record or handshake
            * layer calling this function again.
            */
-          return 0;
+          ret = 0;
+          goto cleanup;
         }
       else /* all other messages -> implicit ack (receive of next flight) */
         {
@@ -303,20 +310,22 @@ unsigned int timeout;
   if (ret < 0)
     {
       ret = gnutls_assert_val(ret);
-      goto cleanup;
+      goto end_flight;
     }
 
   ret = 0;
 
-cleanup:
-  if (buf != NULL)
-    gnutls_free(buf);
+end_flight:
   _gnutls_dtls_log ("DTLS[%p]: End of flight transmission.\n", session);
 
   session->internals.dtls.flight_init = 0;
   drop_usage_count(session, send_buffer);
   _mbuffer_head_clear(send_buffer);
 
+cleanup:
+  if (buf != NULL)
+    gnutls_free(buf);
+
   /* SENDING -> WAITING state transition */
   return ret;
 
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c
index c048fea..d270650 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -563,8 +563,6 @@ read_key_mem (gnutls_certificate_credentials_t res,
   return 0;
 }
 
-#ifdef ENABLE_PKCS11
-
 /* Reads a private key from a token.
  */
 static int
@@ -773,8 +771,6 @@ cleanup:
   return ret;
 }
 
-#endif /* ENABLE_PKCS11 */
-
 /* Reads a certificate file
  */
 static int
@@ -1590,8 +1586,6 @@ gnutls_certificate_set_x509_trust_file 
(gnutls_certificate_credentials_t cred,
   return ret;
 }
 
-#ifdef ENABLE_PKI
-
 static int
 parse_pem_crl_mem (gnutls_x509_trust_list_t tlist, 
                    const char * input_crl, unsigned int input_crl_size)
@@ -2294,5 +2288,3 @@ gnutls_certificate_free_crls 
(gnutls_certificate_credentials_t sc)
   /* do nothing for now */
   return;
 }
-
-#endif
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 415e282..183ac94 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -1656,20 +1656,43 @@ gnutls_ecc_curve_t 
gnutls_ecc_curve_get(gnutls_session_t session);
   int gnutls_hex2bin (const char *hex_data, size_t hex_size,
                       void *bin_data, size_t * bin_size);
 
-  /* ssh style functions */
-  int gnutls_verify_stored_pubkey(const char* file, 
-                            const char* application,
+  /* Trust on first use (or ssh like) functions */
+
+  /* stores the provided information to a database
+   */
+  typedef int (*gnutls_trust_db_store_func) (const char* db_name, 
+                                             const char* host,
+                                             const char* service,
+                                             time_t expiration,
+                                             const gnutls_datum_t* pubkey);
+  
+  /* searches for the provided host/service pair that match the
+   * provided public key in the database. */
+  typedef int (*gnutls_trust_db_retr_func) (const char* db_name, 
+                                            const char* host,
+                                            const char* service,
+                                            const gnutls_datum_t *pubkey);
+  
+  typedef struct {
+    gnutls_trust_db_store_func store;
+    gnutls_trust_db_retr_func retrieve;
+  } trust_storage_st;
+  
+  int gnutls_verify_stored_pubkey(const char* db_name, 
+                            const trust_storage_st * tdb,
                             const char* host,
                             const char* service,
                             gnutls_certificate_type_t cert_type,
                             const gnutls_datum_t * cert, unsigned int flags);
 
-  int gnutls_store_pubkey(const char* file, 
-                    const char* application,
+  int gnutls_store_pubkey(const char* db_name,
+                    const trust_storage_st * tdb,
                     const char* host,
                     const char* service,
                     gnutls_certificate_type_t cert_type,
-                    const gnutls_datum_t * cert, unsigned int flags);
+                    const gnutls_datum_t * cert, 
+                    time_t expiration,
+                    unsigned int flags);
 
 
   /* Gnutls error codes. The mapping to a TLS alert is also shown in
diff --git a/lib/system.c b/lib/system.c
index 0829759..a2a9091 100644
--- a/lib/system.c
+++ b/lib/system.c
@@ -306,7 +306,7 @@ const char *home_dir = getenv ("HOME");
       
       home_dir = tmp_home_dir;
     }
-#elsif defined(HAVE_GETPWUID_R)
+#elif defined(HAVE_GETPWUID_R)
   if (home_dir == NULL || home_dir[0] == '\0')
     {
       struct passwd *pwd;
diff --git a/lib/verify-ssh.c b/lib/verify-ssh.c
index 8d6562f..4d085a1 100644
--- a/lib/verify-ssh.c
+++ b/lib/verify-ssh.c
@@ -38,16 +38,26 @@
 static int raw_pubkey_to_base64(gnutls_datum_t* pubkey);
 static int x509_crt_to_raw_pubkey(const gnutls_datum_t * cert, gnutls_datum_t 
*rpubkey);
 static int pgp_crt_to_raw_pubkey(const gnutls_datum_t * cert, gnutls_datum_t 
*rpubkey);
-static int find_stored_pubkey(const char* file, const char* application,
+static int find_stored_pubkey(const char* file, 
                               const char* host, const char* service, 
                               const gnutls_datum_t* skey);
+static 
+int store_pubkey(const char* db_name, const char* host,
+                 const char* service, time_t expiration, const gnutls_datum_t* 
pubkey);
+
 static int find_config_file(char* file, size_t max_size);
 #define MAX_FILENAME 512
 
+static const trust_storage_st default_storage =
+{
+  store_pubkey,
+  find_stored_pubkey
+};
+
 /**
  * gnutls_verify_stored_pubkey:
- * @file: A file specifying the stored keys (use NULL for the default)
- * @application: non-NULL with an application name if this key is 
application-specific
+ * @db_name: A file specifying the stored keys (use NULL for the default)
+ * @tdb: A database structure or NULL to use the default
  * @host: The peer's name
  * @service: non-NULL if this key is specific to a service (e.g. http)
  * @cert_type: The type of the certificate
@@ -58,6 +68,17 @@ static int find_config_file(char* file, size_t max_size);
  * a list of stored public keys.  The @service field if non-NULL should
  * be a port number.
  *
+ * The @tdb variable if non-null specifies a custom back-end for
+ * the storage and retrieval of entries. If it is NULL then the
+ * default file back-end will be used.
+ *
+ * Note that if the custom storage back-end is provided the
+ * retrieval function should return %GNUTLS_E_CERTIFICATE_KEY_MISMATCH
+ * if the host/service pair is found but key doesn't match,
+ * %GNUTLS_E_NO_CERTIFICATE_FOUND if no such host/service with
+ * the given key is found, and 0 if it was found. The storage
+ * function should return 0 on success.
+ *
  * Returns: If no associated public key is found
  * then %GNUTLS_E_NO_CERTIFICATE_FOUND will be returned. If a key
  * is found but does not match %GNUTLS_E_CERTIFICATE_KEY_MISMATCH
@@ -67,8 +88,8 @@ static int find_config_file(char* file, size_t max_size);
  * Since: 3.0.0
  **/
 int
-gnutls_verify_stored_pubkey(const char* file, 
-                            const char* application,
+gnutls_verify_stored_pubkey(const char* db_name, 
+                            const trust_storage_st *tdb,
                             const char* host,
                             const char* service,
                             gnutls_certificate_type_t cert_type,
@@ -81,14 +102,17 @@ char local_file[MAX_FILENAME];
   if (cert_type != GNUTLS_CRT_X509 && cert_type != GNUTLS_CRT_OPENPGP)
     return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
 
-  if (file == NULL)
+  if (db_name == NULL && tdb == NULL)
     {
       ret = find_config_file(local_file, sizeof(local_file));
       if (ret < 0)
         return gnutls_assert_val(ret);
-      file = local_file;
+      db_name = local_file;
     }
 
+  if (tdb == NULL)
+    tdb = &default_storage;
+
   if (cert_type == GNUTLS_CRT_X509)
     ret = x509_crt_to_raw_pubkey(cert, &pubkey);
   else
@@ -107,25 +131,25 @@ char local_file[MAX_FILENAME];
       goto cleanup;
     }
 
-  ret = find_stored_pubkey(file, application, host, service, &pubkey);
+  ret = tdb->retrieve(db_name, host, service, &pubkey);
   if (ret < 0)
     return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
-  
 
 cleanup:
   gnutls_free(pubkey.data);
   return ret;
 }
 
-static int parse_line(char* line, const char* application,
-                      size_t application_len,
+static int parse_line(char* line, 
                       const char* host, size_t host_len,
                       const char* service, size_t service_len,
+                      time_t now,
                       const gnutls_datum_t *skey)
 {
 char* p, *kp;
 char* savep = NULL;
 size_t kp_len;
+time_t expiration;
 
   /* read version */
   p = strtok_r(line, "|", &savep);
@@ -135,31 +159,32 @@ size_t kp_len;
   if (strncmp(p, "g0", 2) != 0)
     return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
 
-  /* read application */
+  /* read host */
   p = strtok_r(NULL, "|", &savep);
   if (p == NULL)
     return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
     
-  if (p[0] != '*' && strcmp(p, application)!=0)
+  if (p[0] != '*' && strcmp(p, host) != 0)
     return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
 
-  /* read host */
+  /* read service */
   p = strtok_r(NULL, "|", &savep);
   if (p == NULL)
     return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
     
-  if (p[0] != '*' && strcmp(p, host) != 0)
+  if (p[0] != '*' && strcmp(p, service) != 0)
     return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
 
-  /* read service */
+  /* read expiration */
   p = strtok_r(NULL, "|", &savep);
   if (p == NULL)
     return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
     
-  if (p[0] != '*' && strcmp(p, service) != 0)
-    return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
+  expiration = (time_t)atol(p);
+  if (expiration > 0 && now > expiration)
+    return gnutls_assert_val(GNUTLS_E_EXPIRED);
 
-  /* read service */
+  /* read key */
   kp = strtok_r(NULL, "|", &savep);
   if (kp == NULL)
     return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
@@ -180,7 +205,7 @@ size_t kp_len;
 
 /* Returns the base64 key if found 
  */
-static int find_stored_pubkey(const char* file, const char* application,
+static int find_stored_pubkey(const char* file, 
                              const char* host, const char* service, 
                              const gnutls_datum_t* skey)
 {
@@ -188,11 +213,11 @@ FILE* fd;
 char* line = NULL;
 size_t line_size = 0;
 int ret, l2, mismatch = 0;
-size_t application_len = 0, host_len = 0, service_len = 0;
+size_t host_len = 0, service_len = 0;
+time_t now = gnutls_time(0);
 
   if (host != NULL) host_len = strlen(host);
   if (service != NULL) service_len = strlen(service);
-  if (application != NULL) application_len = strlen(application);
 
   fd = fopen(file, "rb");
   if (fd == NULL)
@@ -203,8 +228,7 @@ size_t application_len = 0, host_len = 0, service_len = 0;
       l2 = getline(&line, &line_size, fd);
       if (l2 > 0)
         {
-          ret = parse_line(line, application, application_len,
-                          host, host_len, service, service_len, skey);
+          ret = parse_line(line, host, host_len, service, service_len, now, 
skey);
           if (ret == 0) /* found */
             {
               goto cleanup;
@@ -377,20 +401,48 @@ cleanup:
   return ret;
 }
 
+static 
+int store_pubkey(const char* db_name, const char* host,
+                 const char* service, time_t expiration, 
+                 const gnutls_datum_t* pubkey)
+{
+FILE* fd;
+
+  fd = fopen(db_name, "ab+");
+  if (fd == NULL)
+    return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
+
+  if (service == NULL) service = "*";
+  if (host == NULL) host = "*";
+
+  fprintf(fd, "|g0|%s|%s|%lu|%.*s\n", host, service, (unsigned 
long)expiration, 
+    pubkey->size, pubkey->data);
+  
+  fclose(fd);
+  
+  return 0;
+}
+
 /**
  * gnutls_store_pubkey:
- * @file: A file specifying the stored keys (use NULL for the default)
- * @application: non-NULL with an application name if this key is 
application-specific
+ * @db_name: A file specifying the stored keys (use NULL for the default)
+ * @tdb: A database structure or NULL to use the default
  * @host: The peer's name
  * @service: non-NULL if this key is specific to a service (e.g. http)
  * @cert_type: The type of the certificate
  * @cert: The data of the certificate
+ * @expiration: The expiration time (use 0 to disable expiration)
  * @flags: should be 0.
  *
  * This function will store to verify the provided certificate to 
- * the list of stored public keys. 
+ * the list of stored public keys. The key will be considered valid until 
+ * the provided expiration time.
  *
- * Note that this function is not thread safe.
+ * The @tdb variable if non-null specifies a custom back-end for
+ * the storage and retrieval of entries. If it is NULL then the
+ * default file back-end will be used.
+ *
+ * Note that this function is not thread safe with the default backend.
  *
  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
  *   negative error value.
@@ -398,12 +450,14 @@ cleanup:
  * Since: 3.0.0
  **/
 int
-gnutls_store_pubkey(const char* file, 
-                    const char* application,
+gnutls_store_pubkey(const char* db_name, 
+                    const trust_storage_st* tdb,
                     const char* host,
                     const char* service,
                     gnutls_certificate_type_t cert_type,
-                    const gnutls_datum_t * cert, unsigned int flags)
+                    const gnutls_datum_t * cert, 
+                    time_t expiration,
+                    unsigned int flags)
 {
 FILE* fd = NULL;
 gnutls_datum_t pubkey = { NULL, 0 };
@@ -413,7 +467,7 @@ char local_file[MAX_FILENAME];
   if (cert_type != GNUTLS_CRT_X509 && cert_type != GNUTLS_CRT_OPENPGP)
     return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
   
-  if (file == NULL)
+  if (db_name == NULL && tdb == NULL)
     {
       ret = _gnutls_find_config_path(local_file, sizeof(local_file));
       if (ret < 0)
@@ -425,8 +479,11 @@ char local_file[MAX_FILENAME];
       ret = find_config_file(local_file, sizeof(local_file));
       if (ret < 0)
         return gnutls_assert_val(ret);
-      file = local_file;
+      db_name = local_file;
     }
+
+  if (tdb == NULL)
+    tdb = &default_storage;
     
   if (cert_type == GNUTLS_CRT_X509)
     ret = x509_crt_to_raw_pubkey(cert, &pubkey);
@@ -445,20 +502,9 @@ char local_file[MAX_FILENAME];
       goto cleanup;
     }
 
-  _gnutls_debug_log("Configuration file: %s\n", file);
-
-  fd = fopen(file, "ab+");
-  if (fd == NULL)
-    {
-      ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR);
-      goto cleanup;
-    }
-
-  if (application == NULL) application = "*";
-  if (service == NULL) service = "*";
-  if (host == NULL) host = "*";
+  _gnutls_debug_log("Configuration file: %s\n", db_name);
 
-  fprintf(fd, "|g0|%s|%s|%s|%.*s\n", application, host, service, pubkey.size, 
pubkey.data);
+  tdb->store(db_name, host, service, expiration, &pubkey);
 
   ret = 0;
 
diff --git a/lib/x509/crl.c b/lib/x509/crl.c
index c1b9005..46712bc 100644
--- a/lib/x509/crl.c
+++ b/lib/x509/crl.c
@@ -23,8 +23,6 @@
 #include <gnutls_int.h>
 #include <libtasn1.h>
 
-#ifdef ENABLE_PKI
-
 #include <gnutls_datum.h>
 #include <gnutls_global.h>
 #include <gnutls_errors.h>
@@ -1300,4 +1298,3 @@ error:
   return ret;
 }
 
-#endif
diff --git a/lib/x509/crl_write.c b/lib/x509/crl_write.c
index 32b8570..9964551 100644
--- a/lib/x509/crl_write.c
+++ b/lib/x509/crl_write.c
@@ -25,8 +25,6 @@
 
 #include <gnutls_int.h>
 
-#ifdef ENABLE_PKI
-
 #include <gnutls_datum.h>
 #include <gnutls_global.h>
 #include <gnutls_errors.h>
@@ -508,4 +506,3 @@ gnutls_x509_crl_privkey_sign (gnutls_x509_crl_t crl, 
gnutls_x509_crt_t issuer,
   return 0;
 }
 
-#endif /* ENABLE_PKI */
diff --git a/lib/x509/crq.c b/lib/x509/crq.c
index a7e56f5..e21341e 100644
--- a/lib/x509/crq.c
+++ b/lib/x509/crq.c
@@ -26,8 +26,6 @@
 
 #include <gnutls_int.h>
 
-#ifdef ENABLE_PKI
-
 #include <gnutls_datum.h>
 #include <gnutls_global.h>
 #include <gnutls_errors.h>
@@ -2492,5 +2490,3 @@ cleanup:
   return ret;
 }
 
-#endif /* ENABLE_PKI */
-
diff --git a/lib/x509/extensions.c b/lib/x509/extensions.c
index 166e63d..a429bfe 100644
--- a/lib/x509/extensions.c
+++ b/lib/x509/extensions.c
@@ -514,7 +514,6 @@ _gnutls_x509_crl_set_extension (gnutls_x509_crl_t crl,
                         ext_data, critical);
 }
 
-#ifdef ENABLE_PKI
 int
 _gnutls_x509_crq_set_extension (gnutls_x509_crq_t crq,
                                 const char *ext_id,
@@ -608,8 +607,6 @@ _gnutls_x509_crq_set_extension (gnutls_x509_crq_t crq,
   return 0;
 }
 
-#endif
-
 /* Here we only extract the KeyUsage field, from the DER encoded
  * extension.
  */
diff --git a/lib/x509/mpi.c b/lib/x509/mpi.c
index f69eb4c..baef1ee 100644
--- a/lib/x509/mpi.c
+++ b/lib/x509/mpi.c
@@ -160,8 +160,6 @@ _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
                                "tbsCertificate.subjectPublicKeyInfo", params);
 }
 
-#ifdef ENABLE_PKI
-
 /* Extracts DSA and RSA parameters from a certificate.
  */
 int
@@ -175,9 +173,6 @@ _gnutls_x509_crq_get_mpis (gnutls_x509_crq_t cert,
                                params);
 }
 
-#endif
-
-
 /*
  * This function writes and encodes the parameters for DSS or RSA keys.
  * This is the "signatureAlgorithm" fields.
diff --git a/lib/x509/output.c b/lib/x509/output.c
index 827845f..a16ec4a 100644
--- a/lib/x509/output.c
+++ b/lib/x509/output.c
@@ -437,8 +437,6 @@ print_key_usage (gnutls_buffer_st * str, const char 
*prefix, int type,
     addf (str, _("%s\t\t\tKey decipher only.\n"), prefix);
 }
 
-#ifdef ENABLE_PKI
-
 static void
 print_crldist (gnutls_buffer_st * str, gnutls_x509_crt_t cert)
 {
@@ -600,8 +598,6 @@ print_key_purpose (gnutls_buffer_st * str, const char 
*prefix, int type,
     }
 }
 
-#endif
-
 static void
 print_basic (gnutls_buffer_st * str, const char *prefix, int type,
              cert_type_t cert)
@@ -967,10 +963,7 @@ print_extensions (gnutls_buffer_st * str, const char 
*prefix, int type,
           addf (str, _("%s\t\tKey Purpose (%s):\n"), prefix,
                 critical ? _("critical") : _("not critical"));
 
-#ifdef ENABLE_PKI
           print_key_purpose (str, prefix, type, cert);
-#endif
-
           keypurpose_idx++;
         }
       else if (strcmp (oid, "2.5.29.17") == 0)
@@ -1014,11 +1007,8 @@ print_extensions (gnutls_buffer_st * str, const char 
*prefix, int type,
           addf (str, _("%s\t\tCRL Distribution points (%s):\n"), prefix,
                 critical ? _("critical") : _("not critical"));
 
-#ifdef ENABLE_PKI
           if (type == TYPE_CRT)
             print_crldist (str, cert.crt);
-#endif
-
           crldist_idx++;
         }
       else if (strcmp (oid, "1.3.6.1.5.5.7.1.14") == 0)
@@ -1252,7 +1242,6 @@ print_cert (gnutls_buffer_st * str, gnutls_x509_crt_t 
cert, int notsigned)
         addf (str, _("\tCertificate Security Level: %s (%d bits)\n"),
               gnutls_sec_param_get_name (gnutls_pk_bits_to_sec_param
                                          (err, bits)), bits);
-#ifdef ENABLE_PKI
         err = gnutls_pubkey_init(&pubkey);
         if (err < 0)
          {
@@ -1347,7 +1336,6 @@ print_cert (gnutls_buffer_st * str, gnutls_x509_crt_t 
cert, int notsigned)
           }
         
         gnutls_pubkey_deinit(pubkey);
-#endif
       }
   }
 
@@ -1736,8 +1724,6 @@ gnutls_x509_crt_print (gnutls_x509_crt_t cert,
     }
 }
 
-#ifdef ENABLE_PKI
-
 static void
 print_crl (gnutls_buffer_st * str, gnutls_x509_crl_t crl, int notsigned)
 {
@@ -2392,4 +2378,3 @@ gnutls_x509_crq_print (gnutls_x509_crq_t crq,
   return ret;
 }
 
-#endif /* ENABLE_PKI */
diff --git a/lib/x509/pkcs12.c b/lib/x509/pkcs12.c
index a20f244..f26fd4f 100644
--- a/lib/x509/pkcs12.c
+++ b/lib/x509/pkcs12.c
@@ -26,8 +26,6 @@
 #include <gnutls_int.h>
 #include <libtasn1.h>
 
-#ifdef ENABLE_PKI
-
 #include <gnutls_datum.h>
 #include <gnutls_global.h>
 #include <gnutls_errors.h>
@@ -1330,5 +1328,3 @@ cleanup:
 
 }
 
-
-#endif /* ENABLE_PKI */
diff --git a/lib/x509/pkcs12_bag.c b/lib/x509/pkcs12_bag.c
index 90a1b78..38d01e9 100644
--- a/lib/x509/pkcs12_bag.c
+++ b/lib/x509/pkcs12_bag.c
@@ -25,8 +25,6 @@
 
 #include <gnutls_int.h>
 
-#ifdef ENABLE_PKI
-
 #include <gnutls_datum.h>
 #include <gnutls_global.h>
 #include <gnutls_errors.h>
@@ -827,6 +825,3 @@ gnutls_pkcs12_bag_encrypt (gnutls_pkcs12_bag_t bag, const 
char *pass,
 
   return 0;
 }
-
-
-#endif /* ENABLE_PKI */
diff --git a/lib/x509/pkcs12_encr.c b/lib/x509/pkcs12_encr.c
index 680e069..68b5286 100644
--- a/lib/x509/pkcs12_encr.c
+++ b/lib/x509/pkcs12_encr.c
@@ -21,8 +21,6 @@
 
 #include <gnutls_int.h>
 
-#ifdef ENABLE_PKI
-
 #include <gnutls_mpi.h>
 #include <gnutls_errors.h>
 #include <x509_int.h>
@@ -196,4 +194,3 @@ cleanup:
   return rc;
 }
 
-#endif /* ENABLE_PKI */
diff --git a/lib/x509/pkcs7.c b/lib/x509/pkcs7.c
index fa0f554..6e2e405 100644
--- a/lib/x509/pkcs7.c
+++ b/lib/x509/pkcs7.c
@@ -26,8 +26,6 @@
 #include <gnutls_int.h>
 #include <libtasn1.h>
 
-#ifdef ENABLE_PKI
-
 #include <gnutls_datum.h>
 #include <gnutls_global.h>
 #include <gnutls_errors.h>
@@ -1028,5 +1026,4 @@ cleanup:
     asn1_delete_structure (&c2);
   return result;
 }
-
-#endif /* ENABLE_PKI */
+ 
\ No newline at end of file
diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c
index 089acd0..4050127 100644
--- a/lib/x509/privkey.c
+++ b/lib/x509/privkey.c
@@ -544,14 +544,12 @@ gnutls_x509_privkey_import (gnutls_x509_privkey_t key,
 
 failover:
   /* Try PKCS #8 */
-#ifdef ENABLE_PKI
   if (result == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
     {
       _gnutls_debug_log ("Falling back to PKCS #8 key decoding\n");
       result = gnutls_x509_privkey_import_pkcs8 (key, data, format,
                                                  NULL, GNUTLS_PKCS_PLAIN);
     }
-#endif
 
   if (need_free)
     _gnutls_free_datum (&_data);
@@ -1430,7 +1428,6 @@ gnutls_x509_privkey_get_key_id (gnutls_x509_privkey_t key,
 }
 
 
-#ifdef ENABLE_PKI
 /*-
  * _gnutls_x509_privkey_sign_hash2:
  * @signer: Holds the signer's key
@@ -1647,4 +1644,3 @@ gnutls_x509_privkey_fix (gnutls_x509_privkey_t key)
   return 0;
 }
 
-#endif
diff --git a/lib/x509/privkey_pkcs8.c b/lib/x509/privkey_pkcs8.c
index 2006095..dc0be38 100644
--- a/lib/x509/privkey_pkcs8.c
+++ b/lib/x509/privkey_pkcs8.c
@@ -22,8 +22,6 @@
 
 #include <gnutls_int.h>
 
-#ifdef ENABLE_PKI
-
 #include <gnutls_datum.h>
 #include <gnutls_global.h>
 #include <gnutls_errors.h>
@@ -2439,5 +2437,3 @@ error:
   return result;
 }
 
-
-#endif
diff --git a/lib/x509/sign.c b/lib/x509/sign.c
index c40a1de..cd9d1be 100644
--- a/lib/x509/sign.c
+++ b/lib/x509/sign.c
@@ -26,8 +26,6 @@
 
 #include <gnutls_int.h>
 
-#ifdef ENABLE_PKI
-
 #include <gnutls_errors.h>
 #include <libtasn1.h>
 #include <gnutls_global.h>
@@ -172,4 +170,3 @@ _gnutls_x509_pkix_sign (ASN1_TYPE src, const char *src_name,
   return 0;
 }
 
-#endif
diff --git a/lib/x509/verify.c b/lib/x509/verify.c
index f80506f..1c34269 100644
--- a/lib/x509/verify.c
+++ b/lib/x509/verify.c
@@ -872,7 +872,6 @@ int i, ret;
 
   /* Check for revoked certificates in the chain. 
    */
-#ifdef ENABLE_PKI
   for (i = 0; i < cert_list_length; i++)
     {
       ret = gnutls_x509_crt_check_revocation (cert_list[i],
@@ -883,7 +882,6 @@ int i, ret;
           *verify |= GNUTLS_CERT_INVALID;
         }
     }
-#endif
 
   return 0;
 }
@@ -917,10 +915,6 @@ gnutls_x509_crt_verify (gnutls_x509_crt_t cert,
   return 0;
 }
 
-
-
-#ifdef ENABLE_PKI
-
 /**
  * gnutls_x509_crl_check_issuer:
  * @crl: is the CRL to be checked
@@ -1146,4 +1140,3 @@ cleanup:
   return result;
 }
 
-#endif
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index d3fbe59..253a241 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -2350,8 +2350,6 @@ gnutls_x509_crt_get_key_id (gnutls_x509_crt_t crt, 
unsigned int flags,
 }
 
 
-#ifdef ENABLE_PKI
-
 /* This is exactly as gnutls_x509_crt_check_revocation() except that
  * it calls func.
  */
@@ -3036,7 +3034,6 @@ cleanup:
 
 }
 
-#endif
 /**
  * gnutls_x509_crt_list_import2:
  * @certs: The structures to store the parsed certificate. Must not be 
initialized.
diff --git a/lib/x509/x509_write.c b/lib/x509/x509_write.c
index dff582c..4e31493 100644
--- a/lib/x509/x509_write.c
+++ b/lib/x509/x509_write.c
@@ -25,8 +25,6 @@
 
 #include <gnutls_int.h>
 
-#ifdef ENABLE_PKI
-
 #include <gnutls_datum.h>
 #include <gnutls_global.h>
 #include <gnutls_errors.h>
@@ -1339,6 +1337,3 @@ gnutls_x509_crt_privkey_sign (gnutls_x509_crt_t crt, 
gnutls_x509_crt_t issuer,
 
   return 0;
 }
-
-
-#endif /* ENABLE_PKI */
diff --git a/m4/hooks.m4 b/m4/hooks.m4
index d74d92c..09b6500 100644
--- a/m4/hooks.m4
+++ b/m4/hooks.m4
@@ -39,9 +39,9 @@ AC_DEFUN([LIBGNUTLS_HOOKS],
   # Interfaces changed/added/removed:   CURRENT++       REVISION=0
   # Interfaces added:                             AGE++
   # Interfaces removed:                           AGE=0
-  AC_SUBST(LT_CURRENT, 33)
-  AC_SUBST(LT_REVISION, 1)
-  AC_SUBST(LT_AGE, 5)
+  AC_SUBST(LT_CURRENT, 34)
+  AC_SUBST(LT_REVISION, 0)
+  AC_SUBST(LT_AGE, 6)
 
   AC_SUBST(LT_SSL_CURRENT, 27)
   AC_SUBST(LT_SSL_REVISION, 1)
@@ -132,6 +132,7 @@ fi
     AC_MSG_WARN([C99 macros not supported. This may affect compiling.])
   ])
 
+  ac_enable_srp=yes
   AC_MSG_CHECKING([whether to disable SRP authentication support])
   AC_ARG_ENABLE(srp-authentication,
     AS_HELP_STRING([--disable-srp-authentication],
@@ -146,6 +147,7 @@ fi
   fi
   AM_CONDITIONAL(ENABLE_SRP, test "$ac_enable_srp" != "no")
   
+  ac_enable_psk=yes
   AC_MSG_CHECKING([whether to disable PSK authentication support])
   AC_ARG_ENABLE(psk-authentication,
     AS_HELP_STRING([--disable-psk-authentication],
@@ -160,6 +162,7 @@ fi
   fi
   AM_CONDITIONAL(ENABLE_PSK, test "$ac_enable_psk" != "no")
   
+  ac_enable_anon=yes
   AC_MSG_CHECKING([whether to disable anonymous authentication support])
   AC_ARG_ENABLE(anon-authentication,
     AS_HELP_STRING([--disable-anon-authentication],
@@ -174,20 +177,6 @@ fi
   fi
   AM_CONDITIONAL(ENABLE_ANON, test "$ac_enable_anon" != "no")
   
-  AC_MSG_CHECKING([whether to disable extra PKI stuff])
-  AC_ARG_ENABLE(extra-pki,
-    AS_HELP_STRING([--disable-extra-pki],
-                   [only enable the basic PKI stuff]),
-    enable_pki=$enableval, enable_pki=yes)
-  if test "$enable_pki" != "yes"; then
-   ac_full=0
-   AC_MSG_RESULT(yes)
-  else
-   AC_MSG_RESULT(no)
-   AC_DEFINE([ENABLE_PKI], 1, [whether to include all the PKCS/PKI stuff])
-  fi
-  AM_CONDITIONAL(ENABLE_PKI, test "$enable_pki" = "yes")
-  
   ac_enable_openpgp=yes
   AC_MSG_CHECKING([whether to disable OpenPGP Certificate authentication 
support])
   AC_ARG_ENABLE(openpgp-authentication,
diff --git a/src/Makefile.am b/src/Makefile.am
index 72d3e6a..33f3ff3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -17,8 +17,14 @@
 # along with this file; if not, write to the Free Software Foundation,
 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
+SUBDIRS =
+
 if ENABLE_CRYWRAP
-SUBDIRS = crywrap
+SUBDIRS += crywrap
+endif
+
+if NEED_LIBOPTS
+SUBDIRS += libopts
 endif
 
 AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
@@ -30,10 +36,7 @@ AM_CPPFLAGS = \
        -I$(srcdir)/../extra/includes   \
        $(LIBOPTS_CFLAGS)
 
-bin_PROGRAMS = gnutls-serv gnutls-cli psktool gnutls-cli-debug
-if ENABLE_PKI
-bin_PROGRAMS += certtool
-endif
+bin_PROGRAMS = gnutls-serv gnutls-cli psktool gnutls-cli-debug certtool
 if ENABLE_SRP
 bin_PROGRAMS += srptool
 endif
diff --git a/src/benchmark-tls.c b/src/benchmark-tls.c
index eb16548..10bcf63 100644
--- a/src/benchmark-tls.c
+++ b/src/benchmark-tls.c
@@ -40,6 +40,8 @@
 #include "../tests/eagain-common.h"
 #include "benchmark.h"
 
+const char* side = "";
+
 #define PRIO_DH 
"NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+DHE-RSA"
 #define PRIO_ECDH 
"NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+ECDHE-RSA:+CURVE-SECP192R1"
 #define PRIO_ECDHE_ECDSA 
"NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+ECDHE-ECDSA:+CURVE-SECP192R1"
@@ -206,7 +208,7 @@ char buffer[64 * 1024];
 
 static void tls_log_func(int level, const char *str)
 {
-    fprintf(stderr, "|<%d>| %s", level, str);
+    fprintf(stderr, "%s|<%d>| %s", side, level, str);
 }
 
 static void test_ciphersuite(const char *cipher_prio, int size)
diff --git a/src/cli-args.def b/src/cli-args.def
index 7f18026..c0d29a6 100644
--- a/src/cli-args.def
+++ b/src/cli-args.def
@@ -37,11 +37,11 @@ flag = {
 };
 
 flag = {
-    name      = ssh;
-    descrip   = "Enable SSH-style authentication";
+    name      = tofu;
+    descrip   = "Enable trust on first use (SSH-style) authentication";
     disabled;
     disable   = "no";
-    doc       = "This option will, in addition to certificate authentication, 
perform authentication based on stored public keys.";
+    doc       = "This option will, in addition to certificate authentication, 
perform authentication based on previously seen public keys.";
 };
 
 flag = {
diff --git a/src/cli.c b/src/cli.c
index a2d653b..e673aad 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -35,6 +35,7 @@
 #include <unistd.h>
 #include <stdint.h>
 #include <fcntl.h>
+#include <netdb.h>
 
 #include <gnutls/gnutls.h>
 #include <gnutls/abstract.h>
@@ -446,16 +447,40 @@ read_yesno (const char *input_str)
   return 0;
 }
 
+/* converts a textual service or port to
+ * a service.
+ */
+static const char* port_to_service(const char* sport)
+{
+unsigned int port;
+struct servent * sr;
+  
+  port = atoi(sport);
+  if (port == 0) return sport;
+
+  port = htons(port);
+
+  sr = getservbyport(port, udp?"udp":"tcp");
+  if (sr == NULL)
+    {
+      fprintf(stderr, "Warning: getservbyport() failed. Using port number as 
service.\n");
+      return sport;
+    }
+
+  return sr->s_name;
+}
+
 static int
 cert_verify_callback (gnutls_session_t session)
 {
   int rc;
   unsigned int status = 0;
-  int ssh = ENABLED_OPT(SSH);
+  int ssh = ENABLED_OPT(TOFU);
+  const char* txt_service;
 
   if (!x509_cafile && !pgp_keyring)
     return 0;
-
+    
   rc = cert_verify(session, hostname);
   if (rc == 0)
     {
@@ -487,13 +512,15 @@ cert_verify_callback (gnutls_session_t session)
           fprintf(stderr, "Cannot obtain peer's certificate!\n");
           return -1;
         }
+
+      txt_service = port_to_service(service);
       
-      rc = gnutls_verify_stored_pubkey(NULL, NULL, hostname, service, 
GNUTLS_CRT_X509,
-                                       cert, 0);
+      rc = gnutls_verify_stored_pubkey(NULL, NULL, hostname, txt_service, 
+                                       GNUTLS_CRT_X509, cert, 0);
       if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND)
         {
           print_cert_info_compact(session);
-          fprintf(stderr, "Host %s has never been contacted before and is not 
in the trusted list.\n", hostname);
+          fprintf(stderr, "Host %s (%s) has never been contacted before.\n", 
hostname, txt_service);
           if (status == 0)
             fprintf(stderr, "Its certificate is valid for %s.\n", hostname);
 
@@ -521,7 +548,8 @@ cert_verify_callback (gnutls_session_t session)
       
       if (rc != 0)
         {
-          rc = gnutls_store_pubkey(NULL, NULL, hostname, service, 
GNUTLS_CRT_X509, cert, 0);
+          rc = gnutls_store_pubkey(NULL, NULL, hostname, txt_service, 
+                                   GNUTLS_CRT_X509, cert, 0, 0);
           if (rc < 0)
             fprintf(stderr, "Could not store key: %s\n", gnutls_strerror(rc));
         }
@@ -1381,7 +1409,6 @@ init_global_tls_stuff (void)
           printf ("Processed %d CA certificate(s).\n", ret);
         }
     }
-#ifdef ENABLE_PKI
   if (x509_crlfile != NULL)
     {
       ret = gnutls_certificate_set_x509_crl_file (xcred, x509_crlfile,
@@ -1395,7 +1422,6 @@ init_global_tls_stuff (void)
           printf ("Processed %d CRL(s).\n", ret);
         }
     }
-#endif
 
   load_keys ();
 
diff --git a/src/dh.c b/src/dh.c
index 3c0eacb..88845bf 100644
--- a/src/dh.c
+++ b/src/dh.c
@@ -20,8 +20,6 @@
 
 #include <config.h>
 
-#ifdef ENABLE_PKI
-
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -241,4 +239,3 @@ generate_prime (int how, common_info_st * info)
   return 0;
 }
 
-#endif
diff --git a/src/libopts/compat/compat.h b/src/libopts/compat/compat.h
index 230aef9..b288a7c 100644
--- a/src/libopts/compat/compat.h
+++ b/src/libopts/compat/compat.h
@@ -82,7 +82,9 @@
 #  include <sys/procset.h>
 #endif
 #include <sys/stat.h>
-#include <sys/wait.h>
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
 
 #if defined( HAVE_SOLARIS_SYSINFO )
 #  include <sys/systeminfo.h>
diff --git a/src/libopts/cook.c b/src/libopts/cook.c
index 811ce59..49c12a3 100644
--- a/src/libopts/cook.c
+++ b/src/libopts/cook.c
@@ -59,7 +59,7 @@ contiguous_quote(char ** pps, char * pq, int * lnct_p);
  * err:  @code{NULL} is returned if the string is mal-formed.
 =*/
 unsigned int
-ao_string_cook_escape_char( char const* pzIn, char* pRes, u_int nl )
+ao_string_cook_escape_char( char const* pzIn, char* pRes, unsigned nl )
 {
     unsigned int  res = 1;
 
@@ -282,7 +282,7 @@ ao_string_cook(char * pzScan, int * lnct_p)
              *  THEN we do the full escape character processing
              */
             else if (q != '\'') {
-                int ct = ao_string_cook_escape_char( pzS, pzD-1, (u_int)'\n' );
+                int ct = ao_string_cook_escape_char( pzS, pzD-1, 
(unsigned)'\n' );
                 if (ct == 0)
                     return NULL;
 
diff --git a/src/libopts/makeshell.c b/src/libopts/makeshell.c
index 7b9b6cd..20964ff 100644
--- a/src/libopts/makeshell.c
+++ b/src/libopts/makeshell.c
@@ -471,7 +471,9 @@ optionParseShell(tOptions* pOpts)
         printf("\nenv | grep '^%s_'\n", pOpts->pzPROGNAME);
 
     fflush(stdout);
+#ifdef HAVE_FCHMOD
     fchmod(STDOUT_FILENO, 0755);
+#endif
     fclose(stdout);
     if (ferror(stdout)) {
         fputs(zOutputFail, stderr);
diff --git a/src/libopts/text_mmap.c b/src/libopts/text_mmap.c
index 4a7a9df..e46d594 100644
--- a/src/libopts/text_mmap.c
+++ b/src/libopts/text_mmap.c
@@ -96,7 +96,7 @@ load_text_file(tmap_info_t * mapinfo)
             if (rdct <= 0) {
                 mapinfo->txt_errno = errno;
                 fprintf(stderr, zFSErrReadFile,
-                        errno, strerror(errno), pzFile);
+                        errno, strerror(errno), "mapped file");
                 free(mapinfo->txt_data);
                 return;
             }
diff --git a/src/serv.c b/src/serv.c
index d2277cb..33b0fe9 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -988,7 +988,6 @@ main (int argc, char **argv)
           printf ("Processed %d CA certificate(s).\n", ret);
         }
     }
-#ifdef ENABLE_PKI
   if (x509_crlfile != NULL)
     {
       if ((ret = gnutls_certificate_set_x509_crl_file
@@ -1003,7 +1002,6 @@ main (int argc, char **argv)
           printf ("Processed %d CRL(s).\n", ret);
         }
     }
-#endif
 
 #ifdef ENABLE_OPENPGP
   if (pgp_keyring != NULL)
diff --git a/src/socket.c b/src/socket.c
index 3dc722b..c4d4001 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -31,8 +31,8 @@
 #include <sys/types.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 #ifndef _WIN32
-# include <unistd.h>
 # include <signal.h>
 #endif
 #include <socket.h>
@@ -223,28 +223,3 @@ sockets_init (void)
 #endif
 
 }
-
-/* converts a service name or a port (in string) to a
- * port number. The protocol is assumed to be TCP.
- *
- * returns -1 on error;
- */
-int
-service_to_port (const char *service)
-{
-    int port;
-    struct servent *server_port;
-
-    port = atoi (service);
-    if (port != 0)
-        return port;
-
-    server_port = getservbyname (service, "tcp");
-    if (server_port == NULL)
-      {
-          perror ("getservbyname()");
-          return (-1);
-      }
-
-    return ntohs (server_port->s_port);
-}
diff --git a/src/socket.h b/src/socket.h
index 4846465..141bacb 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -20,4 +20,3 @@ void socket_connect (const socket_st * hd);
 void socket_bye (socket_st * socket);
 
 void sockets_init (void);
-int service_to_port (const char *service);


hooks/post-receive
-- 
GNU gnutls



reply via email to

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