summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2012-11-02 13:46:25 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2012-11-02 13:53:59 +0100
commit2be2aecf9ec3dc662b2df27494862121f9b0ee0b (patch)
treee7ff16d7dee0d7dcca26b38aa76c779c06268bb8
parent1aa734d74ddad776de76807954b3ba5e4647d82d (diff)
downloadgnutls-2be2aecf9ec3dc662b2df27494862121f9b0ee0b.tar.gz
check pathlen constraints.
-rw-r--r--NEWS8
-rw-r--r--lib/gnutls_cert.c25
-rw-r--r--lib/gnutls_int.h1
-rw-r--r--lib/x509/verify.c45
-rwxr-xr-xtests/suite/chain2
-rw-r--r--tests/suite/x509paths/README1
6 files changed, 54 insertions, 28 deletions
diff --git a/NEWS b/NEWS
index ef4f7035e9..79a07b3859 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,10 @@ See the end for copying conditions.
** libgnutls: gnutls_certificate_verify_peers2() will set flags depending on
the available revocation data validity.
+** libgnutls: Added gnutls_certificate_verification_status_print(),
+a function to print the verification status code in human
+readable text.
+
** libgnutls: Added priority string %VERIFY_DISABLE_CRL_CHECKS.
** libgnutls: Simplified certificate verification by adding
@@ -16,8 +20,8 @@ gnutls_certificate_verify_peers3().
for SRTP.
** libgnutls: The X.509 verification functions check the key
-usage bits and output @GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE
-if check fails.
+usage bits and pathlen constraints and on failure output
+GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE.
** libgnutls: gnutls_x509_crl_verify() includes the time
checks.
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index 8c2d27d427..f784cc5f81 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -934,14 +934,14 @@ gnutls_certificate_verification_status_print (unsigned int status,
_gnutls_buffer_init (&str);
if (status == 0)
- _gnutls_buffer_append_str (&str, _("Peer's certificate is trusted. "));
+ _gnutls_buffer_append_str (&str, _("The certificate is trusted. "));
else
- _gnutls_buffer_append_str (&str, _("Peer's certificate is NOT trusted. "));
+ _gnutls_buffer_append_str (&str, _("The certificate is NOT trusted. "));
if (type == GNUTLS_CRT_X509)
{
if (status & GNUTLS_CERT_REVOKED)
- _gnutls_buffer_append_str (&str, _("Peer's certificate chain revoked. "));
+ _gnutls_buffer_append_str (&str, _("The certificate chain revoked. "));
if (status & GNUTLS_CERT_REVOCATION_DATA_TOO_OLD)
_gnutls_buffer_append_str (&str, _("The revocation data are too old. "));
@@ -953,30 +953,33 @@ gnutls_certificate_verification_status_print (unsigned int status,
_gnutls_buffer_append_str (&str, _("The revocation data are issued with a future date. "));
if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
- _gnutls_buffer_append_str (&str, _("Peer's certificate issuer is unknown. "));
+ _gnutls_buffer_append_str (&str, _("The certificate issuer is unknown. "));
if (status & GNUTLS_CERT_SIGNER_NOT_CA)
- _gnutls_buffer_append_str (&str, _("Peer's certificate issuer is not a CA. "));
+ _gnutls_buffer_append_str (&str, _("The certificate issuer is not a CA. "));
}
else if (type == GNUTLS_CRT_OPENPGP)
{
- _gnutls_buffer_append_str (&str, _("Peer's certificate is not trusted. "));
+ _gnutls_buffer_append_str (&str, _("The certificate is not trusted. "));
if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
- _gnutls_buffer_append_str (&str, _("Could not find a signer of the peer's certificate. "));
+ _gnutls_buffer_append_str (&str, _("Could not find a signer of the certificate. "));
if (status & GNUTLS_CERT_REVOKED)
- _gnutls_buffer_append_str (&str, _("Peer's certificate is revoked. "));
+ _gnutls_buffer_append_str (&str, _("The certificate is revoked. "));
}
if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
- _gnutls_buffer_append_str (&str, _("Peer's certificate chain uses insecure algorithm. "));
+ _gnutls_buffer_append_str (&str, _("The certificate chain uses insecure algorithm. "));
+
+ if (status & GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE)
+ _gnutls_buffer_append_str (&str, _("The certificate chain violates the signer's constraints. "));
if (status & GNUTLS_CERT_NOT_ACTIVATED)
- _gnutls_buffer_append_str (&str, _("Peer's certificate chain uses not yet valid certificate. "));
+ _gnutls_buffer_append_str (&str, _("The certificate chain uses not yet valid certificate. "));
if (status & GNUTLS_CERT_EXPIRED)
- _gnutls_buffer_append_str (&str, _("Peer's certificate chain uses expired certificate. "));
+ _gnutls_buffer_append_str (&str, _("The certificate chain uses expired certificate. "));
if (status & GNUTLS_CERT_SIGNATURE_FAILURE)
_gnutls_buffer_append_str (&str, _("The signature in the certificate is invalid. "));
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 68a176ee3c..1081135817 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -202,6 +202,7 @@ typedef enum transport_t
*/
#define DEFAULT_MAX_VERIFY_DEPTH 16
#define DEFAULT_MAX_VERIFY_BITS 16*1024
+#define MAX_VERIFY_DEPTH 4096
#include <gnutls_mem.h>
diff --git a/lib/x509/verify.c b/lib/x509/verify.c
index 0a61869cdf..7cbbb63299 100644
--- a/lib/x509/verify.c
+++ b/lib/x509/verify.c
@@ -113,13 +113,15 @@ cleanup:
*/
static int
check_if_ca (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
+ unsigned int *max_path,
unsigned int flags)
{
gnutls_datum_t cert_signed_data = { NULL, 0 };
gnutls_datum_t issuer_signed_data = { NULL, 0 };
gnutls_datum_t cert_signature = { NULL, 0 };
gnutls_datum_t issuer_signature = { NULL, 0 };
- int result;
+ int pathlen, result;
+ unsigned int ca_status;
/* Check if the issuer is the same with the
* certificate. This is added in order for trusted
@@ -176,9 +178,21 @@ check_if_ca (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
goto cleanup;
}
}
+
+ result = gnutls_x509_crt_get_basic_constraints( issuer, NULL, &ca_status, &pathlen);
+ if (result < 0)
+ {
+ ca_status = 0;
+ pathlen = -1;
+ }
+
+ if (ca_status != 0 && pathlen != -1)
+ {
+ if ((unsigned)pathlen < *max_path)
+ *max_path = pathlen;
+ }
- result = gnutls_x509_crt_get_ca_status (issuer, NULL);
- if (result == 1)
+ if (ca_status != 0)
{
result = 1;
goto cleanup;
@@ -392,6 +406,7 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
unsigned int *output,
gnutls_x509_crt_t * _issuer,
time_t now,
+ unsigned int *max_path,
gnutls_verify_output_function func)
{
gnutls_datum_t cert_signed_data = { NULL, 0 };
@@ -402,18 +417,20 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
if (output)
*output = 0;
-
- if (tcas_size >= 1)
- issuer = find_issuer (cert, trusted_cas, tcas_size);
- else
+
+ if (*max_path == 0)
{
- gnutls_assert ();
- out = GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
+ out = GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE | GNUTLS_CERT_INVALID;
if (output)
*output |= out;
+ gnutls_assert ();
result = 0;
goto cleanup;
}
+ (*max_path)--;
+
+ if (tcas_size >= 1)
+ issuer = find_issuer (cert, trusted_cas, tcas_size);
/* issuer is not in trusted certificate
* authorities.
@@ -437,12 +454,12 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
gnutls_assert ();
return issuer_version;
}
-
+
if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) &&
((flags & GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT)
|| issuer_version != 1))
{
- if (check_if_ca (cert, issuer, flags) == 0)
+ if (check_if_ca (cert, issuer, max_path, flags) == 0)
{
gnutls_assert ();
out = GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID;
@@ -603,6 +620,7 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list,
unsigned int status = 0, output;
time_t now = gnutls_time (0);
gnutls_x509_crt_t issuer = NULL;
+ unsigned int max_path;
if (clist_size > 1)
{
@@ -676,9 +694,10 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list,
* in self signed etc certificates.
*/
output = 0;
+ max_path = MAX_VERIFY_DEPTH;
ret = _gnutls_verify_certificate2 (certificate_list[clist_size - 1],
trusted_cas, tcas_size, flags, &output,
- &issuer, now, func);
+ &issuer, now, &max_path, func);
if (ret == 0)
{
/* if the last certificate in the certificate
@@ -707,7 +726,7 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list,
if ((ret =
_gnutls_verify_certificate2 (certificate_list[i - 1],
&certificate_list[i], 1, flags,
- &output, NULL, now, func)) == 0)
+ &output, NULL, now, &max_path, func)) == 0)
{
status |= output;
status |= GNUTLS_CERT_INVALID;
diff --git a/tests/suite/chain b/tests/suite/chain
index 35bc541c93..f1967c9811 100755
--- a/tests/suite/chain
+++ b/tests/suite/chain
@@ -24,7 +24,7 @@ CERTTOOL=../../../src/certtool
SUCCESS=" 1 4 7 12 15 16 17 18 24 26 27 30 33 56 57 62 63 "
FAILURE=" 2 3 5 6 8 9 10 11 13 14 19 20 21 22 23 25 28 29 31 32 54 55 58 59 60 61 "
-KNOWN_BUGS=" 15 16 17 18 19 31 32 54 55 58 59 60 61 "
+KNOWN_BUGS=" 15 16 17 18 19 31 32 "
cd x509paths
diff --git a/tests/suite/x509paths/README b/tests/suite/x509paths/README
index 0d5d892b14..d56032dcec 100644
--- a/tests/suite/x509paths/README
+++ b/tests/suite/x509paths/README
@@ -27,4 +27,3 @@ that can verify CRLs on addition. (there is an issue there since the
CRLs that are being added are typically of an intermediate CA which
is not in the trust list to verify them)
-Chain 54-55,58-61: We don't check path length constraints properly. XXX