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_1_3-30-gacca614


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_3_1_3-30-gacca614
Date: Tue, 30 Oct 2012 18:46:23 +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=acca614b0f77ec74d403c1de67d69befa4242b5b

The branch, master has been updated
       via  acca614b0f77ec74d403c1de67d69befa4242b5b (commit)
       via  4ecbf335793e040c74e1e45dd51269c544bb7605 (commit)
       via  c8008cae74231ac83b08a2dc995415f2fea497fc (commit)
       via  1566caaa8063a5b4cd544c97a60cbfedcf6c7a5c (commit)
       via  c1e846124968412b168d43613fdd81a037c762e6 (commit)
       via  3632cb3eaf778507070b8613684586e4e00af68b (commit)
      from  0d19c895785ebbd68e607b92dbc80d70ca06632c (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 acca614b0f77ec74d403c1de67d69befa4242b5b
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Tue Oct 30 19:35:53 2012 +0100

    Documented gnutls_certificate_verification_status_print().

commit 4ecbf335793e040c74e1e45dd51269c544bb7605
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Tue Oct 30 19:18:24 2012 +0100

    Added gnutls_certificate_verification_status_print().
    
    This function simplifies printing the certificate verification status.

commit c8008cae74231ac83b08a2dc995415f2fea497fc
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Tue Oct 30 18:51:50 2012 +0100

    Simplified certificate verification by adding 
gnutls_certificate_verify_peers3().
    
    This function combines the RFC2818 hostname check and chain verification 
check.

commit 1566caaa8063a5b4cd544c97a60cbfedcf6c7a5c
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Tue Oct 30 18:16:40 2012 +0100

    fix compilation when DANE is disabled.

commit c1e846124968412b168d43613fdd81a037c762e6
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Tue Oct 30 18:15:18 2012 +0100

    updated documentation.

commit 3632cb3eaf778507070b8613684586e4e00af68b
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Tue Oct 30 15:49:44 2012 +0100

    Added gnutls_certificate_update_verify_flags() to allow setting new flags 
without overriding any defaults.

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

Summary of changes:
 NEWS                            |   12 ++-
 doc/Makefile.am                 |    1 +
 doc/cha-cert-auth.texi          |   86 +++++-----------------
 doc/cha-cert-auth2.texi         |    2 +-
 doc/cha-gtls-app.texi           |   98 +++++++++++++++++++++---
 doc/examples/ex-client-x509.c   |   65 +++-------------
 doc/examples/ex-verify-ssh.c    |   63 ++++------------
 doc/examples/verify.c           |   65 +++-------------
 lib/gnutls_cert.c               |  149 +++++++++++++++++++++++++++++++++++-
 lib/gnutls_ui.c                 |   25 +++++-
 lib/gnutls_x509.c               |   13 +++-
 lib/gnutls_x509.h               |    1 +
 lib/includes/gnutls/gnutls.h.in |   11 +++
 lib/libgnutls.map               |    3 +
 lib/openpgp/compat.c            |    9 ++
 lib/openpgp/gnutls_openpgp.h    |    1 +
 lib/openpgp/pgp.c               |    2 +-
 lib/x509/output.c               |    6 +-
 lib/x509/rfc2818_hostname.c     |    2 +-
 src/cli.c                       |    2 +
 src/common.c                    |  160 +++------------------------------------
 21 files changed, 373 insertions(+), 403 deletions(-)

diff --git a/NEWS b/NEWS
index b7301b3..20eb366 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,9 @@ the available revocation data validity.
 
 ** libgnutls: Added priority string %VERIFY_DISABLE_CRL_CHECKS.
 
+** libgnutls: Simplified certificate verification by adding
+gnutls_certificate_verify_peers3().
+
 ** gnutls-cli: Added --local-dns option.
 
 ** danetool: Corrected bug that prevented loading PEM files.
@@ -17,9 +20,12 @@ the available revocation data validity.
 
 ** API and ABI modifications:
 gnutls_session_get_id2: Added
-GNUTLS_CERT_REVOCATION_DATA_TOO_OLD: Added.
-GNUTLS_CERT_REVOCATION_DATA_INVALID: Added.
-
+gnutls_certificate_update_verify_flags: Added
+gnutls_certificate_verify_peers3: Added
+gnutls_certificate_verification_status_print: Added
+GNUTLS_CERT_REVOCATION_DATA_TOO_OLD: Added
+GNUTLS_CERT_REVOCATION_DATA_INVALID: Added
+GNUTLS_CERT_UNEXPECTED_OWNER: Added
 
 * Version 3.1.3 (released 2012-10-12)
 
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 7f4a8a6..13e4454 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -396,6 +396,7 @@ DISTCLEANFILES += $(ENUMS) stamp_enums stamp_functions
 
 stamp_functions: gnutls-api.texi x509-api.texi pgp-api.texi pkcs12-api.texi 
tpm-api.texi pkcs11-api.texi abstract-api.texi compat-api.texi dtls-api.texi 
crypto-api.texi ocsp-api.texi tpm-api.texi dane-api.texi
        -mkdir functions
+       -rm -f functions/*.short
        for i in $^; do \
                $(srcdir)/scripts/split-texi.pl functions < $$i; \
        done
diff --git a/doc/cha-cert-auth.texi b/doc/cha-cert-auth.texi
index cb395cb..3f66b61 100644
--- a/doc/cha-cert-auth.texi
+++ b/doc/cha-cert-auth.texi
@@ -281,26 +281,20 @@ authority list may also be set using:
 
@showfuncC{gnutls_certificate_set_x509_trust_file,gnutls_certificate_set_x509_crl_file,gnutls_certificate_set_x509_system_trust}
 
 Then it is not required to setup a trusted list as above.
-The function @funcref{gnutls_certificate_verify_peers2} 
-may then be used to verify the peer's certificate chain. The flags
+The function @funcref{gnutls_certificate_verify_peers3} 
+may then be used to verify the peer's certificate chain and identity. The flags
 are set similarly to the verification functions in the previous section.
 
 There is also the possibility to pass some input to the verification
 functions in the form of flags. For 
@funcref{gnutls_x509_trust_list_verify_crt} the
 flags are passed straightforward, but
address@hidden depends on the flags set by
address@hidden depends on the flags set by
 calling @funcref{gnutls_certificate_set_verify_flags}.  All the available
 flags are part of the enumeration
 @address@hidden@address@hidden shown in @ref{gnutls_certificate_verify_flags}.
 
 @showenumdesc{gnutls_certificate_verify_flags,The 
@address@hidden@address@hidden enumeration.}
 
-Although the verification of a certificate path indicates that the
-certificate is signed by trusted authority, does not reveal anything
-about the peer's identity. It is required to verify if the
-certificate's owner is the one you expect. For more information
-consult @funcref{gnutls_x509_crt_check_hostname}, section @ref{ex:verify} for 
an example, and @xcite{RFC2818}.
-
 
 @node OpenPGP certificates
 @section @acronym{OpenPGP} certificates
@@ -433,7 +427,7 @@ of verification status flags is the same as in the 
@acronym{X.509} certificates
 
 Similarly with X.509 certificates, one needs to specify
 the OpenPGP keyring file in the credentials structure. The certificates
-in this file will be  used by @funcref{gnutls_certificate_verify_peers2}
+in this file will be  used by @funcref{gnutls_certificate_verify_peers3}
 to verify the signatures in the certificate sent by the peer.
 
 @showfuncdesc{gnutls_certificate_set_openpgp_keyring_file}
@@ -442,6 +436,13 @@ to verify the signatures in the certificate sent by the 
peer.
 @section Advanced certificate verification
 @cindex Certificate verification
 
+The verification of X.509 certificates in the HTTPS and other Internet 
protocols is typically 
+done by loading a trusted list of commercial Certificate Authorities
+(see @funcref{gnutls_certificate_set_x509_system_trust}), and using them as 
trusted anchors.
+However, there are several examples (eg. the Diginotar incident) where one of 
these
+authorities was compromised. This risk can be mitigated by using in addition 
to CA certificate verification,
+other verification methods. In this section we list the available in GnuTLS 
methods.
+
 @menu
 * Verifying a certificate using trust on first use authentication::
 * Verifying a certificate using DANE (DNSSEC)::
@@ -453,7 +454,6 @@ to verify the signatures in the certificate sent by the 
peer.
 @cindex SSH-style authentication
 @cindex Trust on first use
 @cindex Key pinning
address@hidden gnutls_certificate_verify_flags
 
 It is possible to use a trust on first use (TOFU) authentication 
 method in GnuTLS. That is the concept used by the SSH programs, where the 
@@ -468,76 +468,25 @@ the trust on first use method.
 Such a hybrid system with X.509 and trust on first use authentication is 
 shown in @ref{Simple client example with SSH-style certificate verification}.
 
address@hidden
address@hidden
-
-In addition to the above the @funcref{gnutls_store_commitment} can be 
-used to implement a key-pinning architecture as in @xcite{KEYPIN}. 
-This provides a way for web server to commit on a public key that is
-not yet active.
-
address@hidden
-
-The storage and verification functions may be used with the default
-text file based back-end, or another back-end may be specified. That
-should contain storage and retrieval functions and specified as below.
-
address@hidden,gnutls_tdb_deinit,gnutls_tdb_set_verify_func,gnutls_tdb_set_store_func,gnutls_tdb_set_store_commitment_func}
+See @ref{Certificate verification} on how to use the available functionality.
 
 @node Verifying a certificate using DANE (DNSSEC)
 @subsection Verifying a certificate using DANE (DNSSEC)
 @cindex verifying certificate paths
 @cindex DANE
 @cindex DNSSEC
address@hidden gnutls_certificate_verify_flags
 
 The DANE protocol is a protocol that can be used to verify TLS certificates
 using the DNS (or better DNSSEC) protocols. The DNS security extensions 
(DNSSEC)
 provide an alternative public key infrastructure to the commercial CAs that
 are typically used to sign TLS certificates. The DANE protocol takes advantage
 of the DNSSEC infrastructure to verify TLS certificates. This can be 
-in addition to the verification by commercial CA infrastructure or 
+in addition to the verification by CA infrastructure or 
 could even replace it where DNSSEC is deployed.
 
 The DANE functionality is provided by the @code{libgnutls-dane} library that 
is shipped
 with GnuTLS and the function prototypes are in @code{gnutls/dane.h}. 
-
address@hidden Using the DANE library
-Since the DANE library is not included in GnuTLS it requires programs
-to be linked against it. This can be achieved with the following commands.
-
address@hidden
-gcc -o foo foo.c `pkg-config gnutls-dane --cflags --libs`
address@hidden example
-
-When a program uses the GNU autoconf system, then the following
-line or similar can be used to detect the presence of the library.
-
address@hidden
-PKG_CHECK_MODULES([LIBDANE], [gnutls-dane >= 3.0.0])
-
-AC_SUBST([LIBDANE_CFLAGS])
-AC_SUBST([LIBDANE_LIBS])
address@hidden example
-
address@hidden DANE library functionality
-
-The library provides high level verification functions which are shown below.
-
address@hidden
-
address@hidden,dane_strerror}
-
-Note that the @code{dane_state_t} structure that is accepted by both
-verification functions is optional. It is required when many queries
-are performed to facilitate caching.
-The following flags are returned by the verify functions to
-indicate the status of the verification.
-
address@hidden,The DANE verification status flags.}
-
-In order to generate a DANE TLSA entry to use in a DNS server 
-you may use danetool (see @ref{danetool Invocation}).
+See @ref{Certificate verification} for information on how to use the library.
 
 @node Digital signatures
 @section Digital signatures
@@ -623,8 +572,9 @@ certificates self-signed using @code{RSA-MD2} or 
@code{RSA-MD5}. The
 certificates in the trusted list are considered trusted irrespective
 of the signature.
 
-If you are using @funcref{gnutls_certificate_verify_peers2} to verify the
+If you are using @funcref{gnutls_certificate_verify_peers3} to verify the
 certificate chain, you can call
address@hidden or
 @funcref{gnutls_certificate_set_verify_flags} with the flags:
 @itemize
 @item @code{GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2}
@@ -633,11 +583,11 @@ certificate chain, you can call
 as in the following example:
 
 @example
-  gnutls_certificate_set_verify_flags (x509cred,
+  gnutls_certificate_update_verify_flags (x509cred,
                                        GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
 @end example
 
-This will tell the verifier algorithm to enable @code{RSA-MD5} when
+This will signal the verifier algorithm to enable @code{RSA-MD5} when
 verifying the certificates.
 
 If you are using @funcref{gnutls_x509_crt_verify} or
diff --git a/doc/cha-cert-auth2.texi b/doc/cha-cert-auth2.texi
index e34f0a4..da00a40 100644
--- a/doc/cha-cert-auth2.texi
+++ b/doc/cha-cert-auth2.texi
@@ -155,7 +155,7 @@ in a CRL and/or perform an OCSP check for the certificate.
 
 Note that in the context of a TLS session the server may provide an
 OCSP response that will used during the TLS certificate verification 
-(see @funcref{gnutls_certificate_verify_peers2}).
+(see @funcref{gnutls_certificate_verify_peers3}).
 You may obtain this response using @funcref{gnutls_ocsp_status_request_get}.
 
 Before performing the OCSP query, the application will need to figure
diff --git a/doc/cha-gtls-app.texi b/doc/cha-gtls-app.texi
index 7b5150b..c853398 100644
--- a/doc/cha-gtls-app.texi
+++ b/doc/cha-gtls-app.texi
@@ -11,7 +11,7 @@
 * Data transfer and termination::
 * Handling alerts::
 * Priority Strings::
-* Advanced and other topics::
+* Advanced topics::
 * Using the cryptographic library::
 * Selecting cryptographic key sizes::
 @end menu
@@ -494,25 +494,27 @@ Certificate verification is possible by loading the 
trusted
 authorities into the credentials structure by using
 the following functions, applicable to X.509 and OpenPGP certificates.
 
address@hidden,gnutls_certificate_set_openpgp_keyring_file}
address@hidden,gnutls_certificate_set_x509_trust_file,gnutls_certificate_set_openpgp_keyring_file}
 
 The peer's certificate is not automatically verified and one 
-should call @funcref{gnutls_certificate_verify_peers2}
-after a successful handshake to verify the certificate's signature.
-Alternative the verification can occur during the handshake
+must call @funcref{gnutls_certificate_verify_peers3}
+after a successful handshake to verify the certificate's signature and the 
owner 
+of the certificate. The verification status returned can be printed using
address@hidden
+
+Alternatively the verification can occur during the handshake
 by using @funcref{gnutls_certificate_set_verify_function}.
 
-In order to report a detailed verification output, an alternative
-way has to be used. For that, one should call 
@funcref{gnutls_certificate_get_peers} 
+The functions above provide a brief verification output. If a
+detailed output is required one should call 
@funcref{gnutls_certificate_get_peers}
 to obtain the raw certificate of the peer and verify it using the
 functions discussed in @ref{X.509 certificates}.
 
address@hidden
address@hidden
 
 @showfuncdesc{gnutls_certificate_set_verify_function}
 
 
-
 @node SRP credentials
 @subsection SRP
 
@@ -1067,11 +1069,12 @@ except TLS 1.2:
     "SECURE128:+SECURE192:-VERS-TLS-ALL:+VERS-TLS1.2"
 @end example
 
address@hidden Advanced and other topics
address@hidden Advanced and other topics
address@hidden Advanced topics
address@hidden Advanced topics
 
 @menu
 * Session resumption::
+* Certificate verification::
 * Parameter generation::
 * Keying Material Exporters::
 * Channel Bindings::
@@ -1130,6 +1133,77 @@ Those keys should be associated with the GnuTLS session 
using
 A server enabling both session tickets and a storage for session data
 would use session tickets when clients support it and the storage otherwise.
 
address@hidden Certificate verification
address@hidden Certificate verification
address@hidden DANE
address@hidden DNSSEC
address@hidden SSH-style authentication
address@hidden Trust on first use
address@hidden Key pinning
address@hidden gnutls_certificate_verify_flags
+
+In this section the functionality for additional certificate verification 
methods is listed. 
+These methods are intended to be used in addition to normal PKI verification, 
in order to reduce 
+the risk of a compromised CA being undetected.
+
address@hidden Trust on first use
+
+The GnuTLS library includes functionlity to use an SSH-like trust on first use 
authentication.
+The available functions to store and verify public keys are listed below.
+
address@hidden
address@hidden
+
+In addition to the above the @funcref{gnutls_store_commitment} can be 
+used to implement a key-pinning architecture as in @xcite{KEYPIN}. 
+This provides a way for web server to commit on a public key that is
+not yet active.
+
address@hidden
+
+The storage and verification functions may be used with the default
+text file based back-end, or another back-end may be specified. That
+should contain storage and retrieval functions and specified as below.
+
address@hidden,gnutls_tdb_deinit,gnutls_tdb_set_verify_func,gnutls_tdb_set_store_func,gnutls_tdb_set_store_commitment_func}
+
address@hidden DANE verification
+Since the DANE library is not included in GnuTLS it requires programs
+to be linked against it. This can be achieved with the following commands.
+
address@hidden
+gcc -o foo foo.c `pkg-config gnutls-dane --cflags --libs`
address@hidden example
+
+When a program uses the GNU autoconf system, then the following
+line or similar can be used to detect the presence of the library.
+
address@hidden
+PKG_CHECK_MODULES([LIBDANE], [gnutls-dane >= 3.0.0])
+
+AC_SUBST([LIBDANE_CFLAGS])
+AC_SUBST([LIBDANE_LIBS])
address@hidden example
+
+The high level functionality provided by the DANE library is shown below.
+
address@hidden
+
address@hidden,dane_strerror}
+
+Note that the @code{dane_state_t} structure that is accepted by both
+verification functions is optional. It is required when many queries
+are performed to facilitate caching.
+The following flags are returned by the verify functions to
+indicate the status of the verification.
+
address@hidden,The DANE verification status flags.}
+
+In order to generate a DANE TLSA entry to use in a DNS server 
+you may use danetool (see @ref{danetool Invocation}).
+
+
+
 @node Parameter generation
 @subsection Parameter generation
 @cindex parameter generation
@@ -1283,6 +1357,8 @@ that only allows the stream cipher ARCFOUR is below.
 NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:+VERS-SSL3.0:-CIPHER-ALL:+ARCFOUR-128:%COMPAT
 @end verbatim
 
+
+
 @node Compatibility with the OpenSSL library
 @subsection Compatibility with the OpenSSL library
 @cindex OpenSSL
diff --git a/doc/examples/ex-client-x509.c b/doc/examples/ex-client-x509.c
index 6939ba3..6e38a15 100644
--- a/doc/examples/ex-client-x509.c
+++ b/doc/examples/ex-client-x509.c
@@ -142,11 +142,9 @@ static int
 _verify_certificate_callback (gnutls_session_t session)
 {
   unsigned int status;
-  const gnutls_datum_t *cert_list;
-  unsigned int cert_list_size;
-  int ret;
-  gnutls_x509_crt_t cert;
+  int ret, type;
   const char *hostname;
+  gnutls_datum_t out;
 
   /* read hostname */
   hostname = gnutls_session_get_ptr (session);
@@ -154,66 +152,25 @@ _verify_certificate_callback (gnutls_session_t session)
   /* This verification function uses the trusted CAs in the credentials
    * structure. So you must have installed one or more CA certificates.
    */
-  ret = gnutls_certificate_verify_peers2 (session, &status);
+  ret = gnutls_certificate_verify_peers3 (session, hostname, &status);
   if (ret < 0)
     {
       printf ("Error\n");
       return GNUTLS_E_CERTIFICATE_ERROR;
     }
 
-  if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
-    printf ("The certificate hasn't got a known issuer.\n");
+  type = gnutls_certificate_type_get (session);
 
-  if (status & GNUTLS_CERT_REVOKED)
-    printf ("The certificate has been revoked.\n");
-
-  if (status & GNUTLS_CERT_EXPIRED)
-    printf ("The certificate has expired\n");
-
-  if (status & GNUTLS_CERT_NOT_ACTIVATED)
-    printf ("The certificate is not yet activated\n");
-
-  if (status & GNUTLS_CERT_INVALID)
-    {
-      printf ("The certificate is not trusted.\n");
-      return GNUTLS_E_CERTIFICATE_ERROR;
-    }
-
-  /* Up to here the process is the same for X.509 certificates and
-   * OpenPGP keys. From now on X.509 certificates are assumed. This can
-   * be easily extended to work with openpgp keys as well.
-   */
-  if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
-    return GNUTLS_E_CERTIFICATE_ERROR;
-
-  if (gnutls_x509_crt_init (&cert) < 0)
-    {
-      printf ("error in initialization\n");
-      return GNUTLS_E_CERTIFICATE_ERROR;
-    }
-
-  cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
-  if (cert_list == NULL)
-    {
-      printf ("No certificate was found!\n");
-      return GNUTLS_E_CERTIFICATE_ERROR;
-    }
-
-  if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0)
-    {
-      printf ("error parsing certificate\n");
-      return GNUTLS_E_CERTIFICATE_ERROR;
-    }
-
-
-  if (!gnutls_x509_crt_check_hostname (cert, hostname))
+  ret = gnutls_certificate_verification_status_print( status, type, &out, 0);
+  if (ret < 0)
     {
-      printf ("The certificate's owner does not match hostname '%s'\n",
-              hostname);
+      printf ("Error\n");
       return GNUTLS_E_CERTIFICATE_ERROR;
     }
-
-  gnutls_x509_crt_deinit (cert);
+  
+  printf ("%s", out.data);
+  
+  gnutls_free(out.data);
 
   /* notify gnutls to continue handshake normally */
   return 0;
diff --git a/doc/examples/ex-verify-ssh.c b/doc/examples/ex-verify-ssh.c
index a748516..9251b78 100644
--- a/doc/examples/ex-verify-ssh.c
+++ b/doc/examples/ex-verify-ssh.c
@@ -22,8 +22,8 @@ _ssh_verify_certificate_callback (gnutls_session_t session)
   unsigned int status;
   const gnutls_datum_t *cert_list;
   unsigned int cert_list_size;
-  int ret;
-  gnutls_x509_crt_t cert;
+  int ret, type;
+  gnutls_datum_t out;
   const char *hostname;
 
   /* read hostname */
@@ -32,41 +32,27 @@ _ssh_verify_certificate_callback (gnutls_session_t session)
   /* This verification function uses the trusted CAs in the credentials
    * structure. So you must have installed one or more CA certificates.
    */
-  ret = gnutls_certificate_verify_peers2 (session, &status);
+  ret = gnutls_certificate_verify_peers3 (session, hostname, &status);
   if (ret < 0)
     {
       printf ("Error\n");
       return GNUTLS_E_CERTIFICATE_ERROR;
     }
+  
+  type = gnutls_certificate_type_get (session);
 
-  if (status & GNUTLS_CERT_INVALID)
-    printf ("The certificate is not trusted.\n");
-
-  if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
-    printf ("The certificate hasn't got a known issuer.\n");
-
-  if (status & GNUTLS_CERT_REVOKED)
-    printf ("The certificate has been revoked.\n");
-
-  if (status & GNUTLS_CERT_EXPIRED)
-    printf ("The certificate has expired\n");
-
-  if (status & GNUTLS_CERT_NOT_ACTIVATED)
-    printf ("The certificate is not yet activated\n");
-
-  /* Up to here the process is the same for X.509 certificates and
-   * OpenPGP keys. From now on X.509 certificates are assumed. This can
-   * be easily extended to work with openpgp keys as well.
-   */
-  if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
-    return GNUTLS_E_CERTIFICATE_ERROR;
-
-  if (gnutls_x509_crt_init (&cert) < 0)
+  ret = gnutls_certificate_verification_status_print( status, type, &out, 0);
+  if (ret < 0)
     {
-      printf ("error in initialization\n");
+      printf ("Error\n");
       return GNUTLS_E_CERTIFICATE_ERROR;
     }
+  
+  printf ("%s", out.data);
+  
+  gnutls_free(out.data);
 
+  /* Do SSH verification */
   cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
   if (cert_list == NULL)
     {
@@ -74,27 +60,9 @@ _ssh_verify_certificate_callback (gnutls_session_t session)
       return GNUTLS_E_CERTIFICATE_ERROR;
     }
 
-  /* This is not a real world example, since we only check the first 
-   * certificate in the given chain.
-   */
-  if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0)
-    {
-      printf ("error parsing certificate\n");
-      return GNUTLS_E_CERTIFICATE_ERROR;
-    }
-
-  if (!gnutls_x509_crt_check_hostname (cert, hostname))
-    {
-      printf ("The certificate's owner does not match hostname '%s'\n",
-              hostname);
-      status |= GNUTLS_CERT_INVALID;
-    }
-
-  gnutls_x509_crt_deinit (cert);
-  
   /* service may be obtained alternatively using getservbyport() */
   ret = gnutls_verify_stored_pubkey(NULL, NULL, hostname, "https", 
-                                    GNUTLS_CRT_X509, &cert_list[0], 0);
+                                    type, &cert_list[0], 0);
   if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
     {
       printf("Host %s is not known.", hostname);
@@ -130,8 +98,7 @@ _ssh_verify_certificate_callback (gnutls_session_t session)
   if (ret != 0)
     {
       ret = gnutls_store_pubkey(NULL, NULL, hostname, "https", 
-                                GNUTLS_CRT_X509, &cert_list[0], 
-                                0, 0);
+                                type, &cert_list[0], 0, 0);
       if (ret < 0)
         printf("gnutls_store_pubkey: %s\n", gnutls_strerror(ret));
     }
diff --git a/doc/examples/verify.c b/doc/examples/verify.c
index d02440a..8fd5931 100644
--- a/doc/examples/verify.c
+++ b/doc/examples/verify.c
@@ -13,11 +13,9 @@
 int verify_certificate_callback (gnutls_session_t session)
 {
   unsigned int status;
-  const gnutls_datum_t *cert_list;
-  unsigned int cert_list_size;
-  int ret;
-  gnutls_x509_crt_t cert;
+  int ret, type;
   const char *hostname;
+  gnutls_datum_t out;
 
   /* read hostname */
   hostname = gnutls_session_get_ptr (session);
@@ -25,66 +23,25 @@ int verify_certificate_callback (gnutls_session_t session)
   /* This verification function uses the trusted CAs in the credentials
    * structure. So you must have installed one or more CA certificates.
    */
-  ret = gnutls_certificate_verify_peers2 (session, &status);
+  ret = gnutls_certificate_verify_peers3 (session, hostname, &status);
   if (ret < 0)
     {
       printf ("Error\n");
       return GNUTLS_E_CERTIFICATE_ERROR;
     }
 
-  if (status & GNUTLS_CERT_INVALID)
-    printf ("The certificate is not trusted.\n");
+  type = gnutls_certificate_type_get (session);
 
-  if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
-    printf ("The certificate hasn't got a known issuer.\n");
-
-  if (status & GNUTLS_CERT_REVOKED)
-    printf ("The certificate has been revoked.\n");
-
-  if (status & GNUTLS_CERT_EXPIRED)
-    printf ("The certificate has expired\n");
-
-  if (status & GNUTLS_CERT_NOT_ACTIVATED)
-    printf ("The certificate is not yet activated\n");
-
-  /* Up to here the process is the same for X.509 certificates and
-   * OpenPGP keys. From now on X.509 certificates are assumed. This can
-   * be easily extended to work with openpgp keys as well.
-   */
-  if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
-    return GNUTLS_E_CERTIFICATE_ERROR;
-
-  if (gnutls_x509_crt_init (&cert) < 0)
-    {
-      printf ("error in initialization\n");
-      return GNUTLS_E_CERTIFICATE_ERROR;
-    }
-
-  cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
-  if (cert_list == NULL)
-    {
-      printf ("No certificate was found!\n");
-      return GNUTLS_E_CERTIFICATE_ERROR;
-    }
-
-  /* This is not a real world example, since we only check the first 
-   * certificate in the given chain.
-   */
-  if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0)
-    {
-      printf ("error parsing certificate\n");
-      return GNUTLS_E_CERTIFICATE_ERROR;
-    }
-
-
-  if (!gnutls_x509_crt_check_hostname (cert, hostname))
+  ret = gnutls_certificate_verification_status_print( status, type, &out, 0);
+  if (ret < 0)
     {
-      printf ("The certificate's owner does not match hostname '%s'\n",
-              hostname);
+      printf ("Error\n");
       return GNUTLS_E_CERTIFICATE_ERROR;
     }
-
-  gnutls_x509_crt_deinit (cert);
+  
+  printf ("%s", out.data);
+  
+  gnutls_free(out.data);
 
   /* notify gnutls to continue handshake normally */
   return 0;
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index d8d437a..f803a65 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -41,6 +41,8 @@
 #ifdef ENABLE_OPENPGP
 #include "openpgp/gnutls_openpgp.h"
 #endif
+#include "gettext.h"
+#define _(String) dgettext (PACKAGE, String)
 
 /**
  * gnutls_certificate_free_keys:
@@ -581,6 +583,7 @@ _gnutls_x509_get_raw_crt_expiration_time (const 
gnutls_datum_t * cert)
  -*/
 static int
 _gnutls_openpgp_crt_verify_peers (gnutls_session_t session,
+                                  const char* hostname,
                                   unsigned int *status)
 {
   cert_auth_info_t info;
@@ -621,7 +624,7 @@ _gnutls_openpgp_crt_verify_peers (gnutls_session_t session,
   /* Verify certificate 
    */
   ret =
-    _gnutls_openpgp_verify_key (cred, &info->raw_certificate_list[0],
+    _gnutls_openpgp_verify_key (cred, hostname, &info->raw_certificate_list[0],
                                 peer_certificate_list_size, status);
 
   if (ret < 0)
@@ -629,7 +632,7 @@ _gnutls_openpgp_crt_verify_peers (gnutls_session_t session,
       gnutls_assert ();
       return ret;
     }
-
+    
   return 0;
 }
 #endif
@@ -677,10 +680,65 @@ gnutls_certificate_verify_peers2 (gnutls_session_t 
session,
   switch (gnutls_certificate_type_get (session))
     {
     case GNUTLS_CRT_X509:
-      return _gnutls_x509_cert_verify_peers (session, status);
+      return _gnutls_x509_cert_verify_peers (session, NULL, status);
+#ifdef ENABLE_OPENPGP
+    case GNUTLS_CRT_OPENPGP:
+      return _gnutls_openpgp_crt_verify_peers (session, NULL, status);
+#endif
+    default:
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+}
+
+/**
+ * gnutls_certificate_verify_peers3:
+ * @session: is a gnutls session
+ * @hostname: is the expected name of the peer
+ * @status: is the output of the verification
+ *
+ * This function will verify the peer's certificate and its name and 
+ * return its status (trusted, invalid etc.).  The value of @status will
+ * be one or more of the gnutls_certificate_status_t flags
+ * bitwise or'd. Note that verification failure does not imply a
+ * negative return value. Only the @status is updated.
+ *
+ * In case the @hostname does not match the %GNUTLS_CERT_UNEXPECTED_OWNER
+ * status flag will be set.
+ *
+ * If available the OCSP Certificate Status extension will be
+ * utilized by this function.
+ * 
+ * To avoid denial of service attacks some
+ * default upper limits regarding the certificate key size and chain
+ * size are set. To override them use gnutls_certificate_set_verify_limits().
+ *
+ * Returns: a negative error code on error and %GNUTLS_E_SUCCESS (0) on 
success.
+ **/
+int
+gnutls_certificate_verify_peers3 (gnutls_session_t session,
+                                  const char* hostname,
+                                  unsigned int *status)
+{
+  cert_auth_info_t info;
+
+  CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
+
+  info = _gnutls_get_auth_info (session);
+  if (info == NULL)
+    {
+      return GNUTLS_E_NO_CERTIFICATE_FOUND;
+    }
+
+  if (info->raw_certificate_list == NULL || info->ncerts == 0)
+    return GNUTLS_E_NO_CERTIFICATE_FOUND;
+
+  switch (gnutls_certificate_type_get (session))
+    {
+    case GNUTLS_CRT_X509:
+      return _gnutls_x509_cert_verify_peers (session, hostname, status);
 #ifdef ENABLE_OPENPGP
     case GNUTLS_CRT_OPENPGP:
-      return _gnutls_openpgp_crt_verify_peers (session, status);
+      return _gnutls_openpgp_crt_verify_peers (session, hostname, status);
 #endif
     default:
       return GNUTLS_E_INVALID_REQUEST;
@@ -846,3 +904,86 @@ _gnutls_check_key_cert_match 
(gnutls_certificate_credentials_t res)
 
   return 0;
 }
+
+/**
+ * gnutls_certificate_verification_status_print:
+ * @status: The status flags to be printed
+ * @type: The certificate type
+ * @out: Newly allocated datum with (0) terminated string.
+ * @flags: should be zero
+ *
+ * This function will pretty print the status of a verification
+ * process -- eg. the one obtained by gnutls_certificate_verify_peers3().
+ *
+ * The output @out needs to be deallocated using gnutls_free().
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_certificate_verification_status_print (unsigned int status,
+                       gnutls_certificate_type_t type,
+                       gnutls_datum_t * out, unsigned int flags)
+{
+  gnutls_buffer_st str;
+  int ret;
+
+  _gnutls_buffer_init (&str);
+
+  if (type == GNUTLS_CRT_X509)
+    {
+      if (status == 0)
+        _gnutls_buffer_append_str (&str, _("- Peer's certificate is 
trusted\n"));
+      else
+        {
+          if (status & GNUTLS_CERT_INVALID)
+            _gnutls_buffer_append_str (&str, _("- Peer's certificate is NOT 
trusted\n"));
+
+          if (status & GNUTLS_CERT_REVOKED)
+            _gnutls_buffer_append_str (&str, _("- Peer's certificate chain 
revoked\n"));
+
+          if (status & GNUTLS_CERT_REVOCATION_DATA_TOO_OLD)
+              _gnutls_buffer_append_str (&str, _("- The revocation data 
provided by the peer are too old\n"));
+
+          if (status & GNUTLS_CERT_REVOCATION_DATA_INVALID)
+              _gnutls_buffer_append_str (&str, _("- The revocation data 
provided by the peer are invalid\n"));
+
+          if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
+              _gnutls_buffer_append_str (&str, _("- Peer's certificate issuer 
is unknown\n"));
+
+          if (status & GNUTLS_CERT_SIGNER_NOT_CA)
+              _gnutls_buffer_append_str (&str, _("- Peer's certificate issuer 
is not a CA\n"));
+        }
+      }
+    else if (type == GNUTLS_CRT_OPENPGP)
+      {
+        if (status == 0)
+          _gnutls_buffer_append_str (&str, _("- Peer's key is valid\n"));
+
+        if (status & GNUTLS_CERT_INVALID)
+          _gnutls_buffer_append_str (&str, _("- Peer's certificate is 
invalid\n"));
+
+        if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
+          _gnutls_buffer_append_str (&str, _("- Could not find a signer of the 
peer's certificate\n"));
+
+        if (status & GNUTLS_CERT_REVOKED)
+          _gnutls_buffer_append_str (&str, _("- Peer's certificate is 
revoked\n"));
+      }
+
+  if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
+    _gnutls_buffer_append_str (&str, _("- Peer's certificate chain uses 
insecure algorithm\n"));
+
+  if (status & GNUTLS_CERT_NOT_ACTIVATED)
+    _gnutls_buffer_append_str (&str, _("- Peer's certificate chain uses not 
yet valid certificate\n"));
+
+  if (status & GNUTLS_CERT_EXPIRED)
+    _gnutls_buffer_append_str (&str, _("- Peer's certificate chain uses 
expired certificate\n"));
+
+  if (status & GNUTLS_CERT_UNEXPECTED_OWNER)
+    _gnutls_buffer_append_str (&str, _("- The name in the certificate does not 
match the expected\n"));
+
+  ret = _gnutls_buffer_to_datum( &str, out);
+  if (out->size > 0) out->size--;
+      
+  return ret;
+}
diff --git a/lib/gnutls_ui.c b/lib/gnutls_ui.c
index 1cd53f2..8b157e7 100644
--- a/lib/gnutls_ui.c
+++ b/lib/gnutls_ui.c
@@ -684,10 +684,9 @@ gnutls_certificate_set_params_function 
(gnutls_certificate_credentials_t res,
  * @res: is a gnutls_certificate_credentials_t structure
  * @flags: are the flags
  *
- * This function will set the flags to be used at verification of the
- * certificates.  Flags must be OR of the
- * #gnutls_certificate_verify_flags enumerations. The default
- * for TLS sessions is GNUTLS_VERIFY_ALLOW_UNSORTED_CHAIN.
+ * This function will set the flags to be used for verification 
+ * of certificates and override any defaults.  The provided flags must be an 
OR of the
+ * #gnutls_certificate_verify_flags enumerations. 
  *
  **/
 void
@@ -698,6 +697,24 @@ gnutls_certificate_set_verify_flags 
(gnutls_certificate_credentials_t
 }
 
 /**
+ * gnutls_certificate_update_verify_flags:
+ * @res: is a gnutls_certificate_credentials_t structure
+ * @flags: are the new flags
+ *
+ * This function will update the default flags to be used for verification 
+ * of certificates.  The provided flags must be an OR of the
+ * #gnutls_certificate_verify_flags enumerations. The default
+ * for TLS sessions is GNUTLS_VERIFY_ALLOW_UNSORTED_CHAIN.
+ *
+ **/
+void
+gnutls_certificate_update_verify_flags (gnutls_certificate_credentials_t
+                                     res, unsigned int flags)
+{
+  res->verify_flags |= flags;
+}
+
+/**
  * gnutls_certificate_set_verify_limits:
  * @res: is a gnutls_certificate_credentials structure
  * @max_bits: is the number of bits of an acceptable certificate (default 8200)
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c
index 19e6c73..cf8dee5 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -191,6 +191,7 @@ cleanup:
  -*/
 int
 _gnutls_x509_cert_verify_peers (gnutls_session_t session,
+                                const char* hostname,
                                 unsigned int *status)
 {
   cert_auth_info_t info;
@@ -306,14 +307,22 @@ skip_ocsp:
                                      peer_certificate_list_size,
                                      verify_flags, status, NULL);
 
-  CLEAR_CERTS;
-
   if (ret < 0)
     {
       gnutls_assert ();
+      CLEAR_CERTS;
       return ret;
     }
 
+  if (hostname)
+    {
+      ret = gnutls_x509_crt_check_hostname( peer_certificate_list[0], 
hostname);
+      if (ret == 0)
+        *status |= GNUTLS_CERT_UNEXPECTED_OWNER;
+    }
+
+  CLEAR_CERTS;
+
   *status |= ocsp_status;
 
   return 0;
diff --git a/lib/gnutls_x509.h b/lib/gnutls_x509.h
index 55340dc..a082cfc 100644
--- a/lib/gnutls_x509.h
+++ b/lib/gnutls_x509.h
@@ -24,6 +24,7 @@
 #include <gnutls/abstract.h>
 
 int _gnutls_x509_cert_verify_peers (gnutls_session_t session,
+                                    const char* hostname,
                                     unsigned int *status);
 
 #define PEM_CERT_SEP2 "-----BEGIN X509 CERTIFICATE"
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index e60914e..98a86fb 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -446,6 +446,7 @@ extern "C"
  * @GNUTLS_CERT_EXPIRED: The certificate has expired.
  * @GNUTLS_CERT_REVOCATION_DATA_TOO_OLD: The OCSP revocation data are too old.
  * @GNUTLS_CERT_REVOCATION_DATA_INVALID: The OCSP revocation data are invalid.
+ * @GNUTLS_CERT_UNEXPECTED_OWNER: The owner is not the expected one.
  *
  * Enumeration of certificate status codes.  Note that the status
  * bits may have different meanings in OpenPGP keys and X.509
@@ -463,6 +464,7 @@ extern "C"
     GNUTLS_CERT_SIGNATURE_FAILURE = 2048,
     GNUTLS_CERT_REVOCATION_DATA_TOO_OLD = 4096,
     GNUTLS_CERT_REVOCATION_DATA_INVALID = 8192,
+    GNUTLS_CERT_UNEXPECTED_OWNER = 16384,
   } gnutls_certificate_status_t;
 
 /**
@@ -1152,6 +1154,8 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t 
session);
                                          gnutls_dh_params_t dh_params);
   void gnutls_certificate_set_verify_flags (gnutls_certificate_credentials_t
                                             res, unsigned int flags);
+  void gnutls_certificate_update_verify_flags (gnutls_certificate_credentials_t
+                                            res, unsigned int flags);
   void gnutls_certificate_set_verify_limits (gnutls_certificate_credentials_t
                                              res, unsigned int max_bits,
                                              unsigned int max_depth);
@@ -1697,6 +1701,13 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t 
session);
   int gnutls_certificate_client_get_request_status (gnutls_session_t session);
   int gnutls_certificate_verify_peers2 (gnutls_session_t session,
                                         unsigned int *status);
+  int gnutls_certificate_verify_peers3 (gnutls_session_t session,
+                                        const char* hostname,
+                                        unsigned int *status);
+
+  int gnutls_certificate_verification_status_print (unsigned int status,
+                       gnutls_certificate_type_t type,
+                       gnutls_datum_t * out, unsigned int flags);
 
   int gnutls_pem_base64_encode (const char *msg, const gnutls_datum_t * data,
                                 char *result, size_t * result_size);
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 751e49b..e20597c 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -858,6 +858,9 @@ GNUTLS_3_1_0 {
        gnutls_pubkey_import_x509_raw;
        gnutls_certificate_get_peers_subkey_id;
        gnutls_session_get_id2;
+       gnutls_certificate_update_verify_flags;
+       gnutls_certificate_verify_peers3;
+       gnutls_certificate_verification_status_print;
 } GNUTLS_3_0_0;
 
 GNUTLS_PRIVATE {
diff --git a/lib/openpgp/compat.c b/lib/openpgp/compat.c
index 7612d3f..ebcb3af 100644
--- a/lib/openpgp/compat.c
+++ b/lib/openpgp/compat.c
@@ -30,6 +30,7 @@
 
 /*-
  * gnutls_openpgp_verify_key:
+ * @hostname: the name of the certificate holder
  * @cert_list: the structure that holds the certificates.
  * @cert_list_lenght: the items in the cert_list.
  * @status: the output of the verification function
@@ -44,6 +45,7 @@
  -*/
 int
 _gnutls_openpgp_verify_key (const gnutls_certificate_credentials_t cred,
+                            const char* hostname,
                             const gnutls_datum_t * cert_list,
                             int cert_list_length, unsigned int *status)
 {
@@ -95,6 +97,13 @@ _gnutls_openpgp_verify_key (const 
gnutls_certificate_credentials_t cred,
   /* If we only checked the self signature. */
   if (!cred->keyring)
     *status |= GNUTLS_CERT_SIGNER_NOT_FOUND;
+    
+  if (hostname)
+    {
+      ret = gnutls_openpgp_crt_check_hostname(key, hostname);
+      if (ret == 0)
+        *status |= GNUTLS_CERT_UNEXPECTED_OWNER;
+    }
 
   ret = 0;
 
diff --git a/lib/openpgp/gnutls_openpgp.h b/lib/openpgp/gnutls_openpgp.h
index 8af869b..4949624 100644
--- a/lib/openpgp/gnutls_openpgp.h
+++ b/lib/openpgp/gnutls_openpgp.h
@@ -57,6 +57,7 @@ _gnutls_openpgp_request_key (gnutls_session_t,
                              uint8_t * key_fpr, int key_fpr_size);
 
 int _gnutls_openpgp_verify_key (const gnutls_certificate_credentials_t,
+                                const char* hostname,
                                 const gnutls_datum_t * cert_list,
                                 int cert_list_length, unsigned int *status);
 int _gnutls_openpgp_fingerprint (const gnutls_datum_t * cert,
diff --git a/lib/openpgp/pgp.c b/lib/openpgp/pgp.c
index 9dc9cc7..e100155 100644
--- a/lib/openpgp/pgp.c
+++ b/lib/openpgp/pgp.c
@@ -603,7 +603,7 @@ gnutls_openpgp_crt_get_revoked_status (gnutls_openpgp_crt_t 
key)
  * given hostname. This is a basic implementation of the matching
  * described in RFC2818 (HTTPS), which takes into account wildcards.
  *
- * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
+ * Returns: non-zero for a successful match, and zero on failure.
  **/
 int
 gnutls_openpgp_crt_check_hostname (gnutls_openpgp_crt_t key,
diff --git a/lib/x509/output.c b/lib/x509/output.c
index 1797b26..ec1a6f2 100644
--- a/lib/x509/output.c
+++ b/lib/x509/output.c
@@ -1711,7 +1711,7 @@ print_oneline (gnutls_buffer_st * str, gnutls_x509_crt_t 
cert)
  * %GNUTLS_CRT_PRINT_ONELINE format will generate one line with some
  * selected fields, which is useful for logging purposes.
  *
- * The output @out needs to be deallocate using gnutls_free().
+ * The output @out needs to be deallocated using gnutls_free().
  *
  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
  *   negative error value.
@@ -2086,7 +2086,7 @@ print_crl (gnutls_buffer_st * str, gnutls_x509_crl_t crl, 
int notsigned)
  * This function will pretty print a X.509 certificate revocation
  * list, suitable for display to a human.
  *
- * The output @out needs to be deallocate using gnutls_free().
+ * The output @out needs to be deallocated using gnutls_free().
  *
  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
  *   negative error value.
@@ -2400,7 +2400,7 @@ print_crq_other (gnutls_buffer_st * str, 
gnutls_x509_crq_t crq)
  * This function will pretty print a certificate request, suitable for
  * display to a human.
  *
- * The output @out needs to be deallocate using gnutls_free().
+ * The output @out needs to be deallocated using gnutls_free().
  *
  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
  *   negative error value.
diff --git a/lib/x509/rfc2818_hostname.c b/lib/x509/rfc2818_hostname.c
index 7d099f3..c53476f 100644
--- a/lib/x509/rfc2818_hostname.c
+++ b/lib/x509/rfc2818_hostname.c
@@ -35,7 +35,7 @@
  * described in RFC2818 (HTTPS), which takes into account wildcards,
  * and the DNSName/IPAddress subject alternative name PKIX extension.
  *
- * Returns: non (0) for a successful match, and (0) on failure.
+ * Returns: non-zero for a successful match, and zero on failure.
  **/
 int
 gnutls_x509_crt_check_hostname (gnutls_x509_crt_t cert, const char *hostname)
diff --git a/src/cli.c b/src/cli.c
index 2cf50d4..a454606 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -399,7 +399,9 @@ cert_verify_callback (gnutls_session_t session)
   int rc;
   unsigned int status = 0;
   int ssh = ENABLED_OPT(TOFU);
+#ifdef HAVE_DANE
   int dane = ENABLED_OPT(DANE);
+#endif
   int ca_verify = ENABLED_OPT(CA_VERIFICATION);
   const char* txt_service;
 
diff --git a/src/common.c b/src/common.c
index 9ef83b6..3e8932a 100644
--- a/src/common.c
+++ b/src/common.c
@@ -192,110 +192,7 @@ print_x509_info (gnutls_session_t session, int flag, int 
print_cert)
       }
 }
 
-/* returns true or false, depending on whether the hostname
- * matches to certificate */
-static int
-verify_x509_hostname (gnutls_session_t session, const char *hostname)
-{
-  gnutls_x509_crt_t crt;
-  const gnutls_datum_t *cert_list;
-  unsigned int cert_list_size = 0;
-  int ret;
-
-  cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
-  if (cert_list_size == 0)
-    {
-      fprintf (stderr, "No certificates found!\n");
-      return 0;
-    }
-
-  gnutls_x509_crt_init (&crt);
-  ret =
-      gnutls_x509_crt_import (crt, &cert_list[0],
-                              GNUTLS_X509_FMT_DER);
-  if (ret < 0)
-    {
-      fprintf (stderr, "Decoding error: %s\n",
-               gnutls_strerror (ret));
-      return 0;
-    }
-
-  /* Check the hostname of the first certificate if it matches
-   * the name of the host we connected to.
-   */
-  if (hostname != NULL)
-    {
-      if (gnutls_x509_crt_check_hostname (crt, hostname) == 0)
-        {
-          printf
-             ("- The hostname in the certificate does NOT match '%s'\n",
-              hostname);
-          ret = 0;
-        }
-      else
-        {
-          printf ("- The hostname in the certificate matches '%s'.\n",
-                  hostname);
-          ret = 1;
-        }
-    }
-
-  gnutls_x509_crt_deinit (crt);
-
-  return ret;
-}
-
 #ifdef ENABLE_OPENPGP
-/* returns true or false, depending on whether the hostname
- * matches to certificate */
-static int
-verify_openpgp_hostname (gnutls_session_t session, const char *hostname)
-{
-  gnutls_openpgp_crt_t crt;
-  const gnutls_datum_t *cert_list;
-  unsigned int cert_list_size = 0;
-  int ret;
-
-  cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
-  if (cert_list_size == 0)
-    {
-      fprintf (stderr, "No certificates found!\n");
-      return 0;
-    }
-
-  gnutls_openpgp_crt_init (&crt);
-  ret =
-      gnutls_openpgp_crt_import (crt, &cert_list[0],
-                              GNUTLS_OPENPGP_FMT_RAW);
-  if (ret < 0)
-    {
-      fprintf (stderr, "Decoding error: %s\n",
-               gnutls_strerror (ret));
-      return 0;
-    }
-
-  /* Check the hostname of the first certificate if it matches
-   * the name of the host we connected to.
-   */
-  if (gnutls_openpgp_crt_check_hostname (crt, hostname) == 0)
-    {
-      printf
-             ("- The hostname in the certificate does NOT match '%s'\n",
-              hostname);
-      ret = 0;
-    }
-  else
-    {
-      printf ("- The hostname in the certificate matches '%s'.\n",
-              hostname);
-      ret = 1;
-    }
-
-  gnutls_openpgp_crt_deinit (crt);
-
-  return ret;
-}
-
 static void
 print_openpgp_info_compact (gnutls_session_t session)
 {
@@ -417,9 +314,10 @@ cert_verify (gnutls_session_t session, const char* 
hostname)
 {
     int rc;
     unsigned int status = 0;
+    gnutls_datum_t out;
     int type;
 
-    rc = gnutls_certificate_verify_peers2 (session, &status);
+    rc = gnutls_certificate_verify_peers3 (session, hostname, &status);
     if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND)
       {
           printf ("- Peer did not send any certificate.\n");
@@ -434,53 +332,17 @@ cert_verify (gnutls_session_t session, const char* 
hostname)
       }
 
     type = gnutls_certificate_type_get (session);
-    if (type == GNUTLS_CRT_X509)
+    rc = gnutls_certificate_verification_status_print( status, type, &out, 0);
+    if (rc < 0)
       {
-
-          if (status & GNUTLS_CERT_REVOKED)
-              printf ("- Peer's certificate chain revoked\n");
-          if (status & GNUTLS_CERT_REVOCATION_DATA_TOO_OLD)
-              printf ("- The revocation data provided by the peer are too 
old\n");
-          if (status & GNUTLS_CERT_REVOCATION_DATA_INVALID)
-              printf ("- The revocation data provided by the peer are 
invalid\n");
-          if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
-              printf ("- Peer's certificate issuer is unknown\n");
-          if (status & GNUTLS_CERT_SIGNER_NOT_CA)
-              printf ("- Peer's certificate issuer is not a CA\n");
-          if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
-              printf
-                  ("- Peer's certificate chain uses insecure algorithm\n");
-          if (status & GNUTLS_CERT_NOT_ACTIVATED)
-              printf
-                  ("- Peer's certificate chain uses not yet valid 
certificate\n");
-          if (status & GNUTLS_CERT_EXPIRED)
-              printf
-                  ("- Peer's certificate chain uses expired certificate\n");
-          if (status & GNUTLS_CERT_INVALID)
-              printf ("- Peer's certificate is NOT trusted\n");
-          else
-              printf ("- Peer's certificate is trusted\n");
-
-          rc = verify_x509_hostname (session, hostname);
-          if (rc == 0) status |= GNUTLS_CERT_INVALID;
+          printf ("- Could not print verification flags (err: %s)\n",
+                  gnutls_strerror (rc));
+          return 0;
       }
-    else if (type == GNUTLS_CRT_OPENPGP)
-      {
-          if (status & GNUTLS_CERT_INVALID)
-              printf ("- Peer's key is invalid\n");
-          else
-              printf ("- Peer's key is valid\n");
-          if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
-              printf ("- Could not find a signer of the peer's key\n");
 
-          rc = verify_openpgp_hostname (session, hostname);
-          if (rc == 0) status |= GNUTLS_CERT_INVALID;
-      }
-    else
-      {
-        fprintf(stderr, "Unknown certificate type\n");
-        status |= GNUTLS_CERT_INVALID;
-      }
+    printf ("%s", out.data);
+    
+    gnutls_free(out.data);
 
     if (status)
       return 0;


hooks/post-receive
-- 
GNU gnutls



reply via email to

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