]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
tests: introduced tests about crypto API failures on illegal use
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 1 Jul 2018 19:03:28 +0000 (21:03 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 2 Jul 2018 12:40:29 +0000 (14:40 +0200)
This ensures that any mistakes in using the crypto API are propagated
to the higher level calls, or result to an abort().

Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
tests/slow/Makefile.am
tests/slow/cipher-api-test.c [new file with mode: 0644]
tests/slow/test-ciphers-api.sh [new file with mode: 0755]

index f387a00c7c1f6a58915645f7fb2674d5469e1fce..2672c1b2f6623bd5722331e10293e6d37f7280fe 100644 (file)
@@ -47,9 +47,10 @@ mac_override_LDFLAGS = $(NETTLE_LIBS) $(HOGWEED_LIBS) $(GMP_LIBS) $(LDADD)
 endif
 
 
-dist_check_SCRIPTS = test-ciphers.sh override-ciphers test-hash-large.sh test-ciphers-common.sh
-check_PROGRAMS = $(ctests) cipher-test cipher-override mac-override cipher-override2 hash-large crypto
-TESTS = $(ctests) test-ciphers.sh override-ciphers test-hash-large.sh crypto
+dist_check_SCRIPTS = test-ciphers.sh override-ciphers test-hash-large.sh test-ciphers-common.sh \
+       test-ciphers-api.sh
+check_PROGRAMS = $(ctests) cipher-test cipher-api-test cipher-override mac-override cipher-override2 hash-large crypto
+TESTS = $(ctests) test-ciphers.sh override-ciphers test-hash-large.sh crypto test-ciphers-api.sh
 
 if HAVE_LIBCRYPTO
 cipher_openssl_compat_LDFLAGS = $(LDADD) $(LIBCRYPTO)
diff --git a/tests/slow/cipher-api-test.c b/tests/slow/cipher-api-test.c
new file mode 100644 (file)
index 0000000..66b1640
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser 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/>
+ *
+ */
+
+#include <config.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+#include <gnutls/abstract.h>
+#include <gnutls/x509.h>
+
+#if defined(WIN32)
+int main(int argc, char **argv)
+{
+       exit(77);
+}
+#else
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <assert.h>
+#include <utils.h>
+
+static void tls_log_func(int level, const char *str)
+{
+       fprintf(stderr, "<%d>| %s", level, str);
+}
+
+static unsigned error_detected = 0;
+
+static void custom_abrt(int sig)
+{
+       error_detected = 1;
+}
+
+static void test_cipher(int algo, unsigned aead)
+{
+       int ret;
+       gnutls_cipher_hd_t ch;
+       uint8_t key16[64];
+       uint8_t iv16[32];
+       uint8_t data[128];
+       gnutls_datum_t key, iv;
+       unsigned auth = 1;
+
+       if (algo == GNUTLS_CIPHER_CHACHA20_POLY1305)
+               auth = 0;
+
+       key.data = key16;
+       key.size = gnutls_cipher_get_key_size(algo);
+       assert(key.size <= sizeof(key16));
+
+       iv.data = iv16;
+       iv.size = gnutls_cipher_get_iv_size(algo);
+       assert(iv.size <= sizeof(iv16));
+
+       memset(iv.data, 0xff, iv.size);
+       memset(key.data, 0xfe, key.size);
+       memset(data, 0xfa, sizeof(data));
+
+       gnutls_global_set_log_function(tls_log_func);
+       if (debug)
+               gnutls_global_set_log_level(4711);
+
+       ret = global_init();
+       if (ret < 0) {
+               fail("Cannot initialize library\n"); /*errcode 1 */
+       }
+
+       ret =
+           gnutls_cipher_init(&ch, algo, &key, &iv);
+       if (ret < 0)
+               fail("gnutls_cipher_init failed\n"); /*errcode 1 */
+
+       if (aead) {
+               if (auth) {
+                       ret = gnutls_cipher_add_auth(ch, data, sizeof(data)-1);
+                       if (ret < 0)
+                               fail("could not add auth data\n");
+
+                       signal(SIGABRT, custom_abrt);
+                       ret = gnutls_cipher_add_auth(ch, data, 16);
+                       signal(SIGABRT, SIG_DFL);
+                       if (ret >= 0 && error_detected == 0)
+                               fail("succeeded in adding auth data data after partial data were given\n");
+               }
+
+               /* try encrypting in a way that violates nettle's AEAD conventions */
+               ret = gnutls_cipher_encrypt(ch, data, sizeof(data)-1);
+               if (ret < 0)
+                       fail("could not encrypt data\n");
+
+               signal(SIGABRT, custom_abrt);
+               ret = gnutls_cipher_encrypt(ch, data, sizeof(data));
+               signal(SIGABRT, SIG_DFL);
+               if (ret >= 0 && error_detected == 0)
+                       fail("succeeded in encrypting partial data after partial data were given\n");
+
+       } else {
+               /* try encrypting in a way that violates nettle's block conventions */
+               signal(SIGABRT, custom_abrt);
+               ret = gnutls_cipher_encrypt(ch, data, sizeof(data)-1);
+               signal(SIGABRT, SIG_DFL);
+               if (ret >= 0 && error_detected == 0)
+                       fail("succeeded in encrypting partial data on block cipher\n");
+       }
+       gnutls_cipher_deinit(ch);
+
+       gnutls_global_deinit();
+       return;
+}
+
+static
+void start(const char *name, int algo, unsigned aead)
+{
+       pid_t child;
+
+       success("trying %s\n", name);
+
+       signal(SIGPIPE, SIG_IGN);
+
+       child = fork();
+       if (child < 0) {
+               perror("fork");
+               fail("fork");
+               return;
+       }
+
+       if (child) {
+               int status;
+               /* parent */
+               wait(&status);
+               check_wait_status(status);
+       } else {
+               test_cipher(algo,aead);
+               exit(0);
+       }
+}
+
+void doit(void)
+{
+       start("aes128-gcm", GNUTLS_CIPHER_AES_128_GCM, 1);
+       start("aes256-gcm", GNUTLS_CIPHER_AES_256_GCM, 1);
+       start("aes128-cbc", GNUTLS_CIPHER_AES_128_CBC, 0);
+       start("aes256-cbc", GNUTLS_CIPHER_AES_256_CBC, 0);
+       start("3des-cbc", GNUTLS_CIPHER_3DES_CBC, 0);
+       if (!gnutls_fips140_mode_enabled()) {
+               start("camellia128-gcm", GNUTLS_CIPHER_CAMELLIA_128_GCM, 1);
+               start("camellia256-gcm", GNUTLS_CIPHER_CAMELLIA_256_GCM, 1);
+               start("chacha20-poly1305", GNUTLS_CIPHER_CHACHA20_POLY1305, 1);
+       }
+}
+
+#endif
diff --git a/tests/slow/test-ciphers-api.sh b/tests/slow/test-ciphers-api.sh
new file mode 100755 (executable)
index 0000000..904ab75
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# Copyright (C) 2014 Red Hat, 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 Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>
+
+srcdir="${srcdir:-.}"
+PROG=./cipher-api-test${EXEEXT}
+
+. "${srcdir}/test-ciphers-common.sh"
+