summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2019-12-26 09:31:19 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2019-12-26 09:31:19 +0000
commit0af5ee946d2e49549ff19968e13d0703b3dcf75e (patch)
tree373f1d010011a93d7f246e79ce3de996d45d256a
parent58a45b8c2fbf2f0ff22e1c7c7762d0cb00855df9 (diff)
parent49d27a55031e72ade52984f5cd94e82e97b46228 (diff)
downloadgnutls-0af5ee946d2e49549ff19968e13d0703b3dcf75e.tar.gz
Merge branch 'tmp-strict-x509-time' into 'master'
Do not tolerate invalid DER time Closes #207 See merge request gnutls/gnutls!1141
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--NEWS5
-rw-r--r--configure.ac1
-rw-r--r--lib/x509/common.h6
-rw-r--r--lib/x509/time.c3
-rw-r--r--m4/hooks.m414
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/cert-tests/Makefile.am7
-rwxr-xr-xtests/cert-tests/reject-invalid-time50
-rw-r--r--tests/strict-der.c115
10 files changed, 201 insertions, 6 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 2283ccc333..d1835a0a7f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -161,7 +161,7 @@ SSL-3.0.Fedora.x86_64:
script:
- ./bootstrap
- mkdir -p build && cd build &&
- dash ../configure --disable-tls13-interop --disable-gcc-warnings --cache-file ../cache/config.cache --enable-sha1-support --enable-ssl3-support --enable-seccomp-tests --disable-doc --disable-guile &&
+ dash ../configure --disable-tls13-interop --disable-gcc-warnings --cache-file ../cache/config.cache --enable-sha1-support --enable-ssl3-support --enable-seccomp-tests --disable-doc --disable-guile --disable-strict-der-time &&
make -j$(nproc) && make check -j$(nproc)
- cd ..
tags:
diff --git a/NEWS b/NEWS
index 67051289ab..51f1f05779 100644
--- a/NEWS
+++ b/NEWS
@@ -10,7 +10,10 @@ See the end for copying conditions.
** libgnutls: Introduced the gnutls_ocsp_req_const_t which is compatible
with gnutls_ocsp_req_t but const.
-** libgnutls: Reject certificates with invalid characters in Time fields (#870).
+** libgnutls: Reject certificates with invalid time fields. That is we reject
+ certificates with invalid characters in Time fields, or invalid time formatting
+ To continue accepting the invalid form compile with --disable-strict-der-time
+ (#207, #870).
** libgnutls: Added support for GOST CNT_IMIT ciphersuite (as defined by
draft-smyshlyaev-tls12-gost-suites-06).
diff --git a/configure.ac b/configure.ac
index aaeb6bfb58..7f27ae6932 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1132,6 +1132,7 @@ if features are disabled)
IDNA support: $idna_support
Non-SuiteB curves: $enable_non_suiteb
FIPS140 mode: $enable_fips
+ Strict DER time: $ac_strict_der_time
])
AC_MSG_NOTICE([Optional libraries:
diff --git a/lib/x509/common.h b/lib/x509/common.h
index 5bbbdfaebd..d36c263a58 100644
--- a/lib/x509/common.h
+++ b/lib/x509/common.h
@@ -279,10 +279,10 @@ int _gnutls_check_if_sorted(gnutls_x509_crt_t * crt, int nr);
inline static int _asn1_strict_der_decode (asn1_node * element, const void *ider,
int len, char *errorDescription)
{
-#ifdef ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME
-# define _ASN1_DER_FLAGS ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME|ASN1_DECODE_FLAG_STRICT_DER
-#else
+#if defined(STRICT_DER_TIME) || !defined(ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME)
# define _ASN1_DER_FLAGS ASN1_DECODE_FLAG_STRICT_DER
+#else
+# define _ASN1_DER_FLAGS (ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME|ASN1_DECODE_FLAG_STRICT_DER)
#endif
return asn1_der_decoding2(element, ider, &len, _ASN1_DER_FLAGS, errorDescription);
}
diff --git a/lib/x509/time.c b/lib/x509/time.c
index 2843d32345..fa10a91002 100644
--- a/lib/x509/time.c
+++ b/lib/x509/time.c
@@ -184,12 +184,15 @@ time_t _gnutls_utcTime2gtime(const char *ttime)
gnutls_assert();
return (time_t) - 1;
}
+
+#ifdef STRICT_DER_TIME
/* Make sure everything else is digits. */
for (i = 0; i < len - 1; i++) {
if (c_isdigit(ttime[i]))
continue;
return gnutls_assert_val((time_t)-1);
}
+#endif
xx[2] = 0;
/* get the year
diff --git a/m4/hooks.m4 b/m4/hooks.m4
index 34a5b38eb9..49367bd1da 100644
--- a/m4/hooks.m4
+++ b/m4/hooks.m4
@@ -144,6 +144,20 @@ LIBTASN1_MINIMUM=4.9
AC_MSG_WARN([C99 macros not supported. This may affect compiling.])
])
+ ac_strict_der_time=yes
+ AC_MSG_CHECKING([whether to disable strict DER time encodings for backwards compatibility])
+ AC_ARG_ENABLE(strict-der-time,
+ AS_HELP_STRING([--disable-strict-der-time],
+ [allow non compliant DER time values]),
+ ac_strict_der_time=$enableval)
+ if test x$ac_strict_der_time != xno; then
+ AC_MSG_RESULT(no)
+ AC_DEFINE([STRICT_DER_TIME], 1, [force strict DER time constraints])
+ else
+ AC_MSG_RESULT(yes)
+ fi
+ AM_CONDITIONAL(STRICT_DER_TIME, test "$ac_strict_der_time" != "no")
+
ac_allow_sha1=no
AC_MSG_CHECKING([whether to allow SHA1 as an acceptable hash for cert digital signatures])
AC_ARG_ENABLE(sha1-support,
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 74c74b93d0..5b1597a636 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -221,6 +221,10 @@ if HAVE_SECCOMP_TESTS
ctests += dtls-with-seccomp tls-with-seccomp dtls-client-with-seccomp tls-client-with-seccomp
endif
+if STRICT_DER_TIME
+ctests += strict-der
+endif
+
if !DISABLE_SYSTEM_CONFIG
ctests += system-prio-file
endif
diff --git a/tests/cert-tests/Makefile.am b/tests/cert-tests/Makefile.am
index c8abdbf74a..38dd2fb53f 100644
--- a/tests/cert-tests/Makefile.am
+++ b/tests/cert-tests/Makefile.am
@@ -111,11 +111,16 @@ dist_check_SCRIPTS = pathlen aki invalid-sig email \
pkcs12 certtool-crl-decoding pkcs12-encode pkcs12-corner-cases inhibit-anypolicy \
smime cert-time alt-chain pkcs7-list-sign pkcs7-eddsa certtool-ecdsa \
key-id pkcs8 pkcs8-decode ecdsa illegal-rsa pkcs8-invalid key-invalid \
- pkcs8-eddsa certtool-subca cert-non-digits-time certtool-verify-profiles
+ pkcs8-eddsa certtool-subca certtool-verify-profiles
dist_check_SCRIPTS += key-id ecdsa pkcs8-invalid key-invalid pkcs8-decode pkcs8 pkcs8-eddsa \
certtool-utf8 crq
+if STRICT_DER_TIME
+dist_check_SCRIPTS += cert-non-digits-time reject-invalid-time
+else
+dist_check_SCRIPTS += tolerate-invalid-time
+endif
if WANT_TEST_SUITE
dist_check_SCRIPTS += provable-dh-default
diff --git a/tests/cert-tests/reject-invalid-time b/tests/cert-tests/reject-invalid-time
new file mode 100755
index 0000000000..39aa5c4ca5
--- /dev/null
+++ b/tests/cert-tests/reject-invalid-time
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+# Copyright (C) 2017 Red Hat, Inc.
+#
+# This file is part of GnuTLS.
+#
+# GnuTLS is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+#
+# GnuTLS is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>
+
+#set -e
+
+srcdir="${srcdir:-.}"
+CERTTOOL="${CERTTOOL:-../../src/certtool${EXEEXT}}"
+PKGCONFIG="${PKG_CONFIG:-$(which pkg-config)}"
+DIFF="${DIFF:-diff -b -B}"
+
+if ! test -x "${CERTTOOL}"; then
+ exit 77
+fi
+
+if ! test -z "${VALGRIND}"; then
+ VALGRIND="${LIBTOOL:-libtool} --mode=execute ${VALGRIND}"
+fi
+
+${PKGCONFIG} --version >/dev/null || exit 77
+
+${PKGCONFIG} --atleast-version=4.12 libtasn1 || exit 77
+
+# Check whether certificates with invalid time fields are accepted
+for file in openssl-invalid-time-format.pem;do
+ ${VALGRIND} "${CERTTOOL}" -i --infile "${srcdir}/data/$file"
+ rc=$?
+
+ if test "${rc}" = "0";then
+ echo "file $file was accepted"
+ exit 1
+ fi
+done
+
+exit 0
diff --git a/tests/strict-der.c b/tests/strict-der.c
new file mode 100644
index 0000000000..8854c744d9
--- /dev/null
+++ b/tests/strict-der.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2011-2012 Free Software Foundation, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GnuTLS; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Parts copied from GnuTLS example programs. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#if !defined(_WIN32)
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <arpa/inet.h>
+#endif
+#include <unistd.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+
+#include "utils.h"
+
+/* Test for gnutls_certificate_get_issuer() and implicitly for
+ * gnutls_trust_list_get_issuer().
+ */
+
+static void tls_log_func(int level, const char *str)
+{
+ fprintf(stderr, "<%d>| %s", level, str);
+}
+
+/* This certificate is modified to contain invalid DER. In older
+ * gnutls versions that would still be parsed and the wrong DER was
+ * "corrected" but now we should reject these */
+static unsigned char cert_pem[] =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIFXzCCBEegAwIBAgIQHYWDpKNVUzEFx4Pq8yjxbTANBgkqhkiG9w0BAQUFADCBtTELMAkGA1UE\n"
+ "BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO\n"
+ "ZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29t\n"
+ "L3JwYSAoYykxMDEvMC0GA1UEAxMmVmVyaVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0g\n"
+ "RzMwHxcOMTQwMjI3MDAwMDAwWgAXDTE1MDIyODIzNTk1OVowZzELMAkGA1UEBhMCVVMxEzARBgNV\n"
+ "BAgTCldhc2hpbmd0b24xEDAOBgNVBAcUB1NlYXR0bGUxGDAWBgNVBAoUD0FtYXpvbi5jb20gSW5j\n"
+ "LjEXMBUGA1UEAxQOd3d3LmFtYXpvbi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\n"
+ "AQCXX4njj63+AK39SJXnf4ove+NO2Z46WgeccZuPUOD89/ucZg9C2K3uwo59QO1t2ZR5IucxVWaV\n"
+ "vSW/9z30hA2ObJco5Cw9o3ZdoFXn0rYUmbWMW+XmL+/bSBDdFPQGfP1WhsFKJJfJ9TIrXBAsTSzH\n"
+ "uC6qFZktvZ1yE0081+bdyOHVHjAQzSPsYFaSUqccMwPvy/sMaI+Um+GCf2PolJJwpI1+j6WmTEVg\n"
+ "RBNHarxtNqpcV3rAFdJ5imL427agMqFur4Iz/OYeoCRBEiKk02ctRzoBaTvF09OQqRg3I4T9bE71\n"
+ "xe1cdWo/sQ4nRiy1tfPBt+aBSiIRMh0Fdle780QFAgMBAAGjggG1MIIBsTBQBgNVHREESTBHghF1\n"
+ "ZWRhdGEuYW1hem9uLmNvbYIKYW1hem9uLmNvbYIIYW16bi5jb22CDHd3dy5hbXpuLmNvbYIOd3d3\n"
+ "LmFtYXpvbi5jb20wCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUH\n"
+ "AwEGCCsGAQUFBwMCMEMGA1UdIAQ8MDowOAYKYIZIAYb4RQEHNjAqMCgGCCsGAQUFBwIBFhxodHRw\n"
+ "czovL3d3dy52ZXJpc2lnbi5jb20vY3BzMB8GA1UdIwQYMBaAFA1EXBZTRMGCfh0gqyX0AWPYvnml\n"
+ "MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9TVlJTZWN1cmUtRzMtY3JsLnZlcmlzaWduLmNvbS9T\n"
+ "VlJTZWN1cmVHMy5jcmwwdgYIKwYBBQUHAQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC52\n"
+ "ZXJpc2lnbi5jb20wQAYIKwYBBQUHMAKGNGh0dHA6Ly9TVlJTZWN1cmUtRzMtYWlhLnZlcmlzaWdu\n"
+ "LmNvbS9TVlJTZWN1cmVHMy5jZXIwDQYJKoZIhvcNAQEFBQADggEBADnmX45CNMkf57rQjB6ef7gf\n"
+ "3r5AfKiGMYdSim4TwU5qcpJicYiyqwQXAQbvZFuZTGzT0jXJROLAsjdHcQiR8D5u7mzVMbJg0kz0\n"
+ "yTsdDM5dFmVWme3l958NZI/I0qCtH+Z/O0cyivOTMARbBJ+92dqQ78U3He9gRNE9VCS3FNgObhwC\n"
+ "cr5tkKTlgSESpSRyBwnLucY4+ci5xjvYndHIzoxII/X9TKOIc2sC+b0H5KP8RcQLAO9G5Nra7+eJ\n"
+ "IC74ZgFvgejqTd2f8QeJljTsNxvG4P7vqQi73fCkTuVfCk5YDtTU2joGAujgBd1EjTIbjWYeoebV\n"
+ "gN5gPKxa/GbGsoQ=\n"
+ "-----END CERTIFICATE-----\n";
+
+const gnutls_datum_t cert = { cert_pem, sizeof(cert_pem) - 1};
+
+void doit(void)
+{
+ int ret;
+ gnutls_x509_crt_t crt;
+
+ /* this must be called once in the program
+ */
+ global_init();
+
+ gnutls_global_set_log_function(tls_log_func);
+ if (debug)
+ gnutls_global_set_log_level(6);
+
+ gnutls_x509_crt_init(&crt);
+
+ ret =
+ gnutls_x509_crt_import(crt, &cert, GNUTLS_X509_FMT_PEM);
+ if (ret >= 0) {
+ fail("gnutls_x509_crt_import allowed loading a cert with invalid DER\n");
+ exit(1);
+ }
+ gnutls_x509_crt_deinit(crt);
+
+ gnutls_global_deinit();
+
+ if (debug)
+ success("success");
+}