]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
allow no certificates to be reported by the gnutls_certificate_retrieve_function...
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 24 Jul 2018 14:38:08 +0000 (16:38 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Tue, 24 Jul 2018 20:06:03 +0000 (22:06 +0200)
In 9829ef9a we introduced a wrapper over the older callback functions
which didn't handle this case.

Resolves #528

Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
lib/cert-cred.c
tests/Makefile.am
tests/empty_retrieve_function.c [new file with mode: 0644]
tests/null_retrieve_function.c

index c219e6e353e1691284837e7669cbe698348ec8b8..2150e903f23286d60f7437d97fa606045f77aa24 100644 (file)
@@ -387,6 +387,13 @@ static int call_legacy_cert_cb1(gnutls_session_t session,
        if (ret < 0)
                return gnutls_assert_val(ret);
 
+       if (st2.ncerts == 0) {
+               *pcert_length = 0;
+               *ocsp_length = 0;
+               *privkey = NULL;
+               return 0;
+       }
+
        if (st2.cert_type != GNUTLS_CRT_X509) {
                gnutls_assert();
                ret = GNUTLS_E_INVALID_REQUEST;
index 1081027c03667209a87b9fc3319065f8d740fc70..c5ae7b8447241d7bcae42dc308348167d9048ec3 100644 (file)
@@ -135,7 +135,7 @@ ctests += mini-record-2 simple gnutls_hmac_fast set_pkcs12_cred cert certuniquei
         tls12-cipher-neg tls11-cipher-neg tls10-cipher-neg ssl30-cipher-neg \
         crq_apis init_roundtrip pkcs12_s2k_pem dn2 tls12-rehandshake-cert-3 \
         nul-in-x509-names x509_altname pkcs12_encode mini-x509 \
-        rng-fork mini-eagain-dtls resume-dtls \
+        rng-fork mini-eagain-dtls resume-dtls empty_retrieve_function \
         tls13-rehandshake-cert gnutls_ext_raw_parse \
         x509cert x509cert-tl infoaccess mini-dtls-hello-verify sign-verify-ed25519-rfc8080 \
         trustdb-tofu dtls-rehandshake-anon mini-alpn mini-dtls-large \
diff --git a/tests/empty_retrieve_function.c b/tests/empty_retrieve_function.c
new file mode 100644 (file)
index 0000000..7ea9204
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2011-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2018 Dmitry Eremin-Solenikov
+ * Copyright (C) 2018 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 <http://www.gnu.org/licenses/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gnutls/abstract.h>
+
+#include "utils.h"
+#include "cert-common.h"
+
+/* Test for behavior of the library when certificate callbacks
+ * return no certificates.
+ */
+
+static int cert_cb1(gnutls_session_t session,
+               const gnutls_datum_t * req_ca_rdn,
+               int nreqs,
+               const gnutls_pk_algorithm_t * pk_algos,
+               int pk_algos_length,
+               gnutls_retr2_st *retr)
+{
+       memset(retr, 0, sizeof(*retr));
+       return 0;
+}
+
+static int cert_cb2(gnutls_session_t session,
+               const gnutls_datum_t *req_ca_rdn,
+               int nreqs,
+               const gnutls_pk_algorithm_t *pk_algos,
+               int pk_algos_length,
+               gnutls_pcert_st** pcert,
+               unsigned int *pcert_length,
+               gnutls_privkey_t *privkey)
+{
+       *pcert_length = 0;
+       *privkey = NULL;
+       *pcert = NULL;
+
+       return 0;
+}
+
+static int cert_cb3(gnutls_session_t session,
+               const struct gnutls_cert_retr_st *info,
+               gnutls_pcert_st **certs,
+               unsigned int *pcert_length,
+               gnutls_ocsp_data_st **ocsp,
+               unsigned int *ocsp_length,
+               gnutls_privkey_t *privkey,
+               unsigned int *flags)
+{
+       *privkey = NULL;
+       *ocsp_length = 0;
+       *pcert_length = 0;
+       return 0;
+}
+
+
+static void tls_log_func(int level, const char *str)
+{
+       fprintf(stderr, "<%d>| %s", level, str);
+}
+
+void doit(void)
+{
+       gnutls_certificate_credentials_t x509_cred;
+       gnutls_certificate_credentials_t clicred;
+       int ret;
+
+       /* 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_certificate_allocate_credentials(&x509_cred);
+
+       ret = gnutls_certificate_set_x509_key_mem(x509_cred, &server_ca3_localhost_cert_chain,
+                                           &server_ca3_key,
+                                           GNUTLS_X509_FMT_PEM);
+       if (ret < 0) {
+               fail("error in error code\n");
+               exit(1);
+       }
+
+       gnutls_certificate_allocate_credentials(&clicred);
+       gnutls_certificate_set_retrieve_function(clicred, cert_cb1);
+       _test_cli_serv(x509_cred, clicred, "NORMAL", "NORMAL", "localhost", NULL, NULL, NULL, 0, 1, GNUTLS_E_NO_CERTIFICATE_FOUND, -1);
+       gnutls_certificate_free_credentials(clicred);
+
+       gnutls_certificate_allocate_credentials(&clicred);
+       gnutls_certificate_set_retrieve_function2(clicred, cert_cb2);
+       _test_cli_serv(x509_cred, clicred, "NORMAL", "NORMAL", "localhost", NULL, NULL, NULL, 0, 1, GNUTLS_E_NO_CERTIFICATE_FOUND, -1);
+       gnutls_certificate_free_credentials(clicred);
+
+       gnutls_certificate_allocate_credentials(&clicred);
+       gnutls_certificate_set_retrieve_function3(clicred, cert_cb3);
+       _test_cli_serv(x509_cred, clicred, "NORMAL", "NORMAL", "localhost", NULL, NULL, NULL, 0, 1, GNUTLS_E_NO_CERTIFICATE_FOUND, -1);
+       gnutls_certificate_free_credentials(clicred);
+
+       gnutls_certificate_free_credentials(x509_cred);
+
+       gnutls_global_deinit();
+
+       if (debug)
+               success("success");
+}
index 4eaee869fcfded758a78e3e83bed13a306fe5764..f165c8b07b7382f62f5e259dd8b4555e0598f035 100644 (file)
  * 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
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
  */
 
-/* Parts copied from GnuTLS example programs. */
-
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -34,8 +31,8 @@
 #include "utils.h"
 #include "cert-common.h"
 
-/* Test for memory allocations in a non-matching key-cert pair loading.
- *
+/* Test for behavior of the library when NULL is set as certificate
+ * function.
  */
 
 static int cert_cb1(gnutls_session_t session,