[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [SCM] GNU gnutls branch, master, updated. gnutls_3_1_3-30-gacca614,
Nikos Mavrogiannopoulos <=