]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
tests: rework tls13-early-data to check key scheduling
authorDaiki Ueno <ueno@gnu.org>
Thu, 29 Apr 2021 09:50:00 +0000 (11:50 +0200)
committerDaiki Ueno <ueno@gnu.org>
Thu, 13 May 2021 09:22:40 +0000 (11:22 +0200)
Signed-off-by: Daiki Ueno <ueno@gnu.org>
tests/Makefile.am
tests/client-secrets.h [new file with mode: 0644]
tests/server-secrets.h [new file with mode: 0644]
tests/tls13-early-data.c

index be847f6ec4ee2ec3f5bd3f358cea84ad9b622d6b..c49fb0b4bda9d0768677c047ccfaeacc6b4b2caf 100644 (file)
@@ -73,7 +73,8 @@ EXTRA_DIST = suppressions.valgrind eagain-common.h cert-common.h test-chains.h \
        testpkcs11-certs/client.key testpkcs11-certs/server.crt testpkcs11-certs/server-tmpl \
        testpkcs11-certs/ca.key testpkcs11-certs/client.crt testpkcs11-certs/client-tmpl testpkcs11-certs/server.key \
        crt_type-neg-common.c \
-       system-override-default-priority-string.bad.config system-override-default-priority-string.none.config system-override-default-priority-string.only-tls13.config
+       system-override-default-priority-string.bad.config system-override-default-priority-string.none.config system-override-default-priority-string.only-tls13.config \
+       client-secrets.h server-secrets.h
 
 AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
 AM_CPPFLAGS = \
diff --git a/tests/client-secrets.h b/tests/client-secrets.h
new file mode 100644 (file)
index 0000000..38915f5
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2021 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/>
+ */
+
+/* This file is autogenerated with tls13-early-data.c.
+ * To reproduce, see the comments in that file.
+ */
+
+#ifndef GNUTLS_TESTS_CLIENT_SECRETS_H
+#define GNUTLS_TESTS_CLIENT_SECRETS_H
+
+static const struct secret client_normal_0[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xdc\x47\xf1\x8b\x33\xd6\x08\x26\xa1\xad\xd9\xb0\x81\xee\x32\x01\xb6\xfc\xce\x9a\xa0\x35\xd1\x30\x61\x85\x2d\xff\x3d\xb1\xe5\x49",
+               (const uint8_t *)"\x24\x24\xaf\xad\xa8\x0e\x40\xc6\xa1\xc3\x05\xff\x5a\xe5\x04\xb9\xc4\xc2\xff\xd6\x2b\x9a\xb8\x43\x85\x78\x92\x1e\x69\x44\x3d\xe2",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\x03\x38\xcf\x43\x68\x90\x01\x7a\xdb\x06\x7d\x92\x08\xcf\x67\x22\x41\xa7\xd3\xe7\x7e\x3a\xaf\x50\xd6\x5c\xaa\xfe\x90\xa4\x87\xa2",
+               (const uint8_t *)"\x5c\x6f\xe8\x8b\xac\x0a\x7b\x04\x76\x9f\xe8\x2a\x7c\x06\x19\x4c\xa7\x51\x5c\xfe\xb9\x31\x25\x0d\x3b\x07\x78\xa9\xdd\x2d\x27\x72",
+       },
+};
+
+static const struct secret client_normal_1[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_EARLY,
+               32,
+               NULL,
+               (const uint8_t *)"\x6f\x16\x97\x8e\x90\x94\x77\x40\x0f\x00\xff\x79\x1c\x15\x20\x19\xeb\xc6\x10\x59\x8f\x92\xac\xab\xe6\xc8\x3c\x12\x30\x94\x91\x12",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xf0\x91\x46\x67\xe1\x36\xb5\xd2\x30\x71\xc9\x1d\xcc\x56\xc3\x9d\xee\xfa\x26\xdb\xe4\xe2\x17\xb7\x3d\xb9\x27\x6a\x7c\xa5\xe7\xa9",
+               NULL,
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               NULL,
+               (const uint8_t *)"\xe7\xf5\x57\x48\x54\x71\xae\xc0\xba\x8d\x12\x90\xc5\x25\xef\xe3\xc7\xea\x39\x09\x24\xe8\x20\x6d\x03\x8d\x80\x1e\xdd\x24\xbb\x5a",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\xf8\xa9\xd5\xe6\x18\xbb\xb7\x07\x1d\xb3\x8f\x78\x61\x30\x63\x01\xa5\x49\xc6\x05\x92\x7f\x67\x98\x72\x76\x75\xb1\x31\x1f\x14\xf9",
+               (const uint8_t *)"\xab\xa3\xf5\x4f\xcc\x3f\xd7\xb7\x23\x73\x51\x6e\x64\xc1\xaa\x6b\xa9\x77\x30\x58\xe6\xd4\xf5\xe9\xa5\xd2\x0d\x35\x42\x65\xda\xf1",
+       },
+};
+
+static const struct secret client_normal_2[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_EARLY,
+               32,
+               NULL,
+               (const uint8_t *)"\x6f\x16\x97\x8e\x90\x94\x77\x40\x0f\x00\xff\x79\x1c\x15\x20\x19\xeb\xc6\x10\x59\x8f\x92\xac\xab\xe6\xc8\x3c\x12\x30\x94\x91\x12",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xf0\x91\x46\x67\xe1\x36\xb5\xd2\x30\x71\xc9\x1d\xcc\x56\xc3\x9d\xee\xfa\x26\xdb\xe4\xe2\x17\xb7\x3d\xb9\x27\x6a\x7c\xa5\xe7\xa9",
+               NULL,
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               NULL,
+               (const uint8_t *)"\xe7\xf5\x57\x48\x54\x71\xae\xc0\xba\x8d\x12\x90\xc5\x25\xef\xe3\xc7\xea\x39\x09\x24\xe8\x20\x6d\x03\x8d\x80\x1e\xdd\x24\xbb\x5a",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\xd8\xdf\x24\xd6\xe1\xdc\x86\x3b\x88\x3d\x2b\xad\x56\xec\x22\xd4\x5c\xaf\xa9\x24\xa3\x90\x20\xa1\xae\x77\x5c\x7d\xef\x3d\xcc\x5b",
+               (const uint8_t *)"\x8d\x02\xe0\xe8\x5f\x9a\xcc\xc7\x8c\x81\x3b\x58\x5f\xa9\xdb\xfd\x98\xb1\x1f\xcc\x3e\x7b\xca\xe7\xef\x05\x4c\x84\x6c\xe1\x11\x25",
+       },
+};
+
+static const struct secret client_small_0[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xdc\x47\xf1\x8b\x33\xd6\x08\x26\xa1\xad\xd9\xb0\x81\xee\x32\x01\xb6\xfc\xce\x9a\xa0\x35\xd1\x30\x61\x85\x2d\xff\x3d\xb1\xe5\x49",
+               (const uint8_t *)"\x24\x24\xaf\xad\xa8\x0e\x40\xc6\xa1\xc3\x05\xff\x5a\xe5\x04\xb9\xc4\xc2\xff\xd6\x2b\x9a\xb8\x43\x85\x78\x92\x1e\x69\x44\x3d\xe2",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\x03\x38\xcf\x43\x68\x90\x01\x7a\xdb\x06\x7d\x92\x08\xcf\x67\x22\x41\xa7\xd3\xe7\x7e\x3a\xaf\x50\xd6\x5c\xaa\xfe\x90\xa4\x87\xa2",
+               (const uint8_t *)"\x5c\x6f\xe8\x8b\xac\x0a\x7b\x04\x76\x9f\xe8\x2a\x7c\x06\x19\x4c\xa7\x51\x5c\xfe\xb9\x31\x25\x0d\x3b\x07\x78\xa9\xdd\x2d\x27\x72",
+       },
+};
+
+static const struct secret client_small_1[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_EARLY,
+               32,
+               NULL,
+               (const uint8_t *)"\x6f\x16\x97\x8e\x90\x94\x77\x40\x0f\x00\xff\x79\x1c\x15\x20\x19\xeb\xc6\x10\x59\x8f\x92\xac\xab\xe6\xc8\x3c\x12\x30\x94\x91\x12",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xf0\x91\x46\x67\xe1\x36\xb5\xd2\x30\x71\xc9\x1d\xcc\x56\xc3\x9d\xee\xfa\x26\xdb\xe4\xe2\x17\xb7\x3d\xb9\x27\x6a\x7c\xa5\xe7\xa9",
+               NULL,
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               NULL,
+               (const uint8_t *)"\xe7\xf5\x57\x48\x54\x71\xae\xc0\xba\x8d\x12\x90\xc5\x25\xef\xe3\xc7\xea\x39\x09\x24\xe8\x20\x6d\x03\x8d\x80\x1e\xdd\x24\xbb\x5a",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\xf8\xa9\xd5\xe6\x18\xbb\xb7\x07\x1d\xb3\x8f\x78\x61\x30\x63\x01\xa5\x49\xc6\x05\x92\x7f\x67\x98\x72\x76\x75\xb1\x31\x1f\x14\xf9",
+               (const uint8_t *)"\xab\xa3\xf5\x4f\xcc\x3f\xd7\xb7\x23\x73\x51\x6e\x64\xc1\xaa\x6b\xa9\x77\x30\x58\xe6\xd4\xf5\xe9\xa5\xd2\x0d\x35\x42\x65\xda\xf1",
+       },
+};
+
+static const struct secret client_small_2[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_EARLY,
+               32,
+               NULL,
+               (const uint8_t *)"\x6f\x16\x97\x8e\x90\x94\x77\x40\x0f\x00\xff\x79\x1c\x15\x20\x19\xeb\xc6\x10\x59\x8f\x92\xac\xab\xe6\xc8\x3c\x12\x30\x94\x91\x12",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xf0\x91\x46\x67\xe1\x36\xb5\xd2\x30\x71\xc9\x1d\xcc\x56\xc3\x9d\xee\xfa\x26\xdb\xe4\xe2\x17\xb7\x3d\xb9\x27\x6a\x7c\xa5\xe7\xa9",
+               NULL,
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               NULL,
+               (const uint8_t *)"\xe7\xf5\x57\x48\x54\x71\xae\xc0\xba\x8d\x12\x90\xc5\x25\xef\xe3\xc7\xea\x39\x09\x24\xe8\x20\x6d\x03\x8d\x80\x1e\xdd\x24\xbb\x5a",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\xd8\xdf\x24\xd6\xe1\xdc\x86\x3b\x88\x3d\x2b\xad\x56\xec\x22\xd4\x5c\xaf\xa9\x24\xa3\x90\x20\xa1\xae\x77\x5c\x7d\xef\x3d\xcc\x5b",
+               (const uint8_t *)"\x8d\x02\xe0\xe8\x5f\x9a\xcc\xc7\x8c\x81\x3b\x58\x5f\xa9\xdb\xfd\x98\xb1\x1f\xcc\x3e\x7b\xca\xe7\xef\x05\x4c\x84\x6c\xe1\x11\x25",
+       },
+};
+
+static const struct secret client_empty_0[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xdc\x47\xf1\x8b\x33\xd6\x08\x26\xa1\xad\xd9\xb0\x81\xee\x32\x01\xb6\xfc\xce\x9a\xa0\x35\xd1\x30\x61\x85\x2d\xff\x3d\xb1\xe5\x49",
+               (const uint8_t *)"\x24\x24\xaf\xad\xa8\x0e\x40\xc6\xa1\xc3\x05\xff\x5a\xe5\x04\xb9\xc4\xc2\xff\xd6\x2b\x9a\xb8\x43\x85\x78\x92\x1e\x69\x44\x3d\xe2",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\x03\x38\xcf\x43\x68\x90\x01\x7a\xdb\x06\x7d\x92\x08\xcf\x67\x22\x41\xa7\xd3\xe7\x7e\x3a\xaf\x50\xd6\x5c\xaa\xfe\x90\xa4\x87\xa2",
+               (const uint8_t *)"\x5c\x6f\xe8\x8b\xac\x0a\x7b\x04\x76\x9f\xe8\x2a\x7c\x06\x19\x4c\xa7\x51\x5c\xfe\xb9\x31\x25\x0d\x3b\x07\x78\xa9\xdd\x2d\x27\x72",
+       },
+};
+
+static const struct secret client_empty_1[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xac\xc2\x07\x48\xba\x3d\x59\x2f\x5f\xce\x79\xda\xa6\x04\x4b\x55\x06\x2c\x9f\x0e\xdf\xda\x42\x51\x9d\x0b\xd9\x39\x4b\x8c\xb2\x7e",
+               (const uint8_t *)"\x87\x07\x01\xdc\x13\xdc\xb7\x93\x26\x53\xff\xa4\x2d\x28\xed\xca\xef\x5b\xa7\x94\x17\x26\xdf\x1f\x8c\x7b\x79\x32\x55\x5e\xcb\x79",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\x73\x16\xe6\x0a\x66\xe1\x81\xd8\x74\xfa\x25\xe3\xf3\x1a\xf2\x4d\x84\xd6\xc6\x7a\x1b\x27\x79\x0a\x09\x9e\xd2\xd4\x1d\xdf\x0f\x53",
+               (const uint8_t *)"\x5f\x8e\xfe\x3e\xa0\x41\x27\x9e\xbb\xba\xf2\xa9\x22\xc6\x06\x58\xb5\xbf\x6e\x29\x3d\x84\x10\x4e\x3f\xe3\xc0\x1f\x7a\x2c\xf5\x21",
+       },
+};
+
+static const struct secret client_empty_2[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xac\xc2\x07\x48\xba\x3d\x59\x2f\x5f\xce\x79\xda\xa6\x04\x4b\x55\x06\x2c\x9f\x0e\xdf\xda\x42\x51\x9d\x0b\xd9\x39\x4b\x8c\xb2\x7e",
+               (const uint8_t *)"\x87\x07\x01\xdc\x13\xdc\xb7\x93\x26\x53\xff\xa4\x2d\x28\xed\xca\xef\x5b\xa7\x94\x17\x26\xdf\x1f\x8c\x7b\x79\x32\x55\x5e\xcb\x79",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\x73\x16\xe6\x0a\x66\xe1\x81\xd8\x74\xfa\x25\xe3\xf3\x1a\xf2\x4d\x84\xd6\xc6\x7a\x1b\x27\x79\x0a\x09\x9e\xd2\xd4\x1d\xdf\x0f\x53",
+               (const uint8_t *)"\x5f\x8e\xfe\x3e\xa0\x41\x27\x9e\xbb\xba\xf2\xa9\x22\xc6\x06\x58\xb5\xbf\x6e\x29\x3d\x84\x10\x4e\x3f\xe3\xc0\x1f\x7a\x2c\xf5\x21",
+       },
+};
+
+static const struct secret client_explicit_0[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xdc\x47\xf1\x8b\x33\xd6\x08\x26\xa1\xad\xd9\xb0\x81\xee\x32\x01\xb6\xfc\xce\x9a\xa0\x35\xd1\x30\x61\x85\x2d\xff\x3d\xb1\xe5\x49",
+               (const uint8_t *)"\x24\x24\xaf\xad\xa8\x0e\x40\xc6\xa1\xc3\x05\xff\x5a\xe5\x04\xb9\xc4\xc2\xff\xd6\x2b\x9a\xb8\x43\x85\x78\x92\x1e\x69\x44\x3d\xe2",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\x03\x38\xcf\x43\x68\x90\x01\x7a\xdb\x06\x7d\x92\x08\xcf\x67\x22\x41\xa7\xd3\xe7\x7e\x3a\xaf\x50\xd6\x5c\xaa\xfe\x90\xa4\x87\xa2",
+               (const uint8_t *)"\x5c\x6f\xe8\x8b\xac\x0a\x7b\x04\x76\x9f\xe8\x2a\x7c\x06\x19\x4c\xa7\x51\x5c\xfe\xb9\x31\x25\x0d\x3b\x07\x78\xa9\xdd\x2d\x27\x72",
+       },
+};
+
+static const struct secret client_explicit_1[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_EARLY,
+               32,
+               NULL,
+               (const uint8_t *)"\x6f\x16\x97\x8e\x90\x94\x77\x40\x0f\x00\xff\x79\x1c\x15\x20\x19\xeb\xc6\x10\x59\x8f\x92\xac\xab\xe6\xc8\x3c\x12\x30\x94\x91\x12",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xf0\x91\x46\x67\xe1\x36\xb5\xd2\x30\x71\xc9\x1d\xcc\x56\xc3\x9d\xee\xfa\x26\xdb\xe4\xe2\x17\xb7\x3d\xb9\x27\x6a\x7c\xa5\xe7\xa9",
+               NULL,
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               NULL,
+               (const uint8_t *)"\xe7\xf5\x57\x48\x54\x71\xae\xc0\xba\x8d\x12\x90\xc5\x25\xef\xe3\xc7\xea\x39\x09\x24\xe8\x20\x6d\x03\x8d\x80\x1e\xdd\x24\xbb\x5a",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\xf8\xa9\xd5\xe6\x18\xbb\xb7\x07\x1d\xb3\x8f\x78\x61\x30\x63\x01\xa5\x49\xc6\x05\x92\x7f\x67\x98\x72\x76\x75\xb1\x31\x1f\x14\xf9",
+               (const uint8_t *)"\xab\xa3\xf5\x4f\xcc\x3f\xd7\xb7\x23\x73\x51\x6e\x64\xc1\xaa\x6b\xa9\x77\x30\x58\xe6\xd4\xf5\xe9\xa5\xd2\x0d\x35\x42\x65\xda\xf1",
+       },
+};
+
+static const struct secret client_explicit_2[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_EARLY,
+               32,
+               NULL,
+               (const uint8_t *)"\x6f\x16\x97\x8e\x90\x94\x77\x40\x0f\x00\xff\x79\x1c\x15\x20\x19\xeb\xc6\x10\x59\x8f\x92\xac\xab\xe6\xc8\x3c\x12\x30\x94\x91\x12",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xf0\x91\x46\x67\xe1\x36\xb5\xd2\x30\x71\xc9\x1d\xcc\x56\xc3\x9d\xee\xfa\x26\xdb\xe4\xe2\x17\xb7\x3d\xb9\x27\x6a\x7c\xa5\xe7\xa9",
+               NULL,
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               NULL,
+               (const uint8_t *)"\xe7\xf5\x57\x48\x54\x71\xae\xc0\xba\x8d\x12\x90\xc5\x25\xef\xe3\xc7\xea\x39\x09\x24\xe8\x20\x6d\x03\x8d\x80\x1e\xdd\x24\xbb\x5a",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\xd8\xdf\x24\xd6\xe1\xdc\x86\x3b\x88\x3d\x2b\xad\x56\xec\x22\xd4\x5c\xaf\xa9\x24\xa3\x90\x20\xa1\xae\x77\x5c\x7d\xef\x3d\xcc\x5b",
+               (const uint8_t *)"\x8d\x02\xe0\xe8\x5f\x9a\xcc\xc7\x8c\x81\x3b\x58\x5f\xa9\xdb\xfd\x98\xb1\x1f\xcc\x3e\x7b\xca\xe7\xef\x05\x4c\x84\x6c\xe1\x11\x25",
+       },
+};
+
+#endif /* GNUTLS_TESTS_CLIENT_SECRETS_H */
diff --git a/tests/server-secrets.h b/tests/server-secrets.h
new file mode 100644 (file)
index 0000000..5c0df49
--- /dev/null
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2021 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/>
+ */
+
+/* This file is autogenerated with tls13-early-data.c.
+ * To reproduce, see the comments in that file.
+ */
+
+#ifndef GNUTLS_TESTS_SERVER_SECRETS_H
+#define GNUTLS_TESTS_SERVER_SECRETS_H
+
+static const struct secret server_normal_0[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\x24\x24\xaf\xad\xa8\x0e\x40\xc6\xa1\xc3\x05\xff\x5a\xe5\x04\xb9\xc4\xc2\xff\xd6\x2b\x9a\xb8\x43\x85\x78\x92\x1e\x69\x44\x3d\xe2",
+               (const uint8_t *)"\xdc\x47\xf1\x8b\x33\xd6\x08\x26\xa1\xad\xd9\xb0\x81\xee\x32\x01\xb6\xfc\xce\x9a\xa0\x35\xd1\x30\x61\x85\x2d\xff\x3d\xb1\xe5\x49",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               NULL,
+               (const uint8_t *)"\x03\x38\xcf\x43\x68\x90\x01\x7a\xdb\x06\x7d\x92\x08\xcf\x67\x22\x41\xa7\xd3\xe7\x7e\x3a\xaf\x50\xd6\x5c\xaa\xfe\x90\xa4\x87\xa2",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\x5c\x6f\xe8\x8b\xac\x0a\x7b\x04\x76\x9f\xe8\x2a\x7c\x06\x19\x4c\xa7\x51\x5c\xfe\xb9\x31\x25\x0d\x3b\x07\x78\xa9\xdd\x2d\x27\x72",
+               NULL,
+       },
+};
+
+static const struct secret server_normal_1[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_EARLY,
+               32,
+               (const uint8_t *)"\x6f\x16\x97\x8e\x90\x94\x77\x40\x0f\x00\xff\x79\x1c\x15\x20\x19\xeb\xc6\x10\x59\x8f\x92\xac\xab\xe6\xc8\x3c\x12\x30\x94\x91\x12",
+               NULL,
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               NULL,
+               (const uint8_t *)"\xf0\x91\x46\x67\xe1\x36\xb5\xd2\x30\x71\xc9\x1d\xcc\x56\xc3\x9d\xee\xfa\x26\xdb\xe4\xe2\x17\xb7\x3d\xb9\x27\x6a\x7c\xa5\xe7\xa9",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xe7\xf5\x57\x48\x54\x71\xae\xc0\xba\x8d\x12\x90\xc5\x25\xef\xe3\xc7\xea\x39\x09\x24\xe8\x20\x6d\x03\x8d\x80\x1e\xdd\x24\xbb\x5a",
+               NULL,
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               NULL,
+               (const uint8_t *)"\xf8\xa9\xd5\xe6\x18\xbb\xb7\x07\x1d\xb3\x8f\x78\x61\x30\x63\x01\xa5\x49\xc6\x05\x92\x7f\x67\x98\x72\x76\x75\xb1\x31\x1f\x14\xf9",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\xab\xa3\xf5\x4f\xcc\x3f\xd7\xb7\x23\x73\x51\x6e\x64\xc1\xaa\x6b\xa9\x77\x30\x58\xe6\xd4\xf5\xe9\xa5\xd2\x0d\x35\x42\x65\xda\xf1",
+               NULL,
+       },
+};
+
+static const struct secret server_normal_2[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xe7\xf5\x57\x48\x54\x71\xae\xc0\xba\x8d\x12\x90\xc5\x25\xef\xe3\xc7\xea\x39\x09\x24\xe8\x20\x6d\x03\x8d\x80\x1e\xdd\x24\xbb\x5a",
+               (const uint8_t *)"\xf0\x91\x46\x67\xe1\x36\xb5\xd2\x30\x71\xc9\x1d\xcc\x56\xc3\x9d\xee\xfa\x26\xdb\xe4\xe2\x17\xb7\x3d\xb9\x27\x6a\x7c\xa5\xe7\xa9",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               NULL,
+               (const uint8_t *)"\xd8\xdf\x24\xd6\xe1\xdc\x86\x3b\x88\x3d\x2b\xad\x56\xec\x22\xd4\x5c\xaf\xa9\x24\xa3\x90\x20\xa1\xae\x77\x5c\x7d\xef\x3d\xcc\x5b",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\x8d\x02\xe0\xe8\x5f\x9a\xcc\xc7\x8c\x81\x3b\x58\x5f\xa9\xdb\xfd\x98\xb1\x1f\xcc\x3e\x7b\xca\xe7\xef\x05\x4c\x84\x6c\xe1\x11\x25",
+               NULL,
+       },
+};
+
+static const struct secret server_small_0[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\x24\x24\xaf\xad\xa8\x0e\x40\xc6\xa1\xc3\x05\xff\x5a\xe5\x04\xb9\xc4\xc2\xff\xd6\x2b\x9a\xb8\x43\x85\x78\x92\x1e\x69\x44\x3d\xe2",
+               (const uint8_t *)"\xdc\x47\xf1\x8b\x33\xd6\x08\x26\xa1\xad\xd9\xb0\x81\xee\x32\x01\xb6\xfc\xce\x9a\xa0\x35\xd1\x30\x61\x85\x2d\xff\x3d\xb1\xe5\x49",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               NULL,
+               (const uint8_t *)"\x03\x38\xcf\x43\x68\x90\x01\x7a\xdb\x06\x7d\x92\x08\xcf\x67\x22\x41\xa7\xd3\xe7\x7e\x3a\xaf\x50\xd6\x5c\xaa\xfe\x90\xa4\x87\xa2",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\x5c\x6f\xe8\x8b\xac\x0a\x7b\x04\x76\x9f\xe8\x2a\x7c\x06\x19\x4c\xa7\x51\x5c\xfe\xb9\x31\x25\x0d\x3b\x07\x78\xa9\xdd\x2d\x27\x72",
+               NULL,
+       },
+};
+
+static const struct secret server_small_1[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_EARLY,
+               32,
+               (const uint8_t *)"\x6f\x16\x97\x8e\x90\x94\x77\x40\x0f\x00\xff\x79\x1c\x15\x20\x19\xeb\xc6\x10\x59\x8f\x92\xac\xab\xe6\xc8\x3c\x12\x30\x94\x91\x12",
+               NULL,
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               NULL,
+               (const uint8_t *)"\xf0\x91\x46\x67\xe1\x36\xb5\xd2\x30\x71\xc9\x1d\xcc\x56\xc3\x9d\xee\xfa\x26\xdb\xe4\xe2\x17\xb7\x3d\xb9\x27\x6a\x7c\xa5\xe7\xa9",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xe7\xf5\x57\x48\x54\x71\xae\xc0\xba\x8d\x12\x90\xc5\x25\xef\xe3\xc7\xea\x39\x09\x24\xe8\x20\x6d\x03\x8d\x80\x1e\xdd\x24\xbb\x5a",
+               NULL,
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               NULL,
+               (const uint8_t *)"\xf8\xa9\xd5\xe6\x18\xbb\xb7\x07\x1d\xb3\x8f\x78\x61\x30\x63\x01\xa5\x49\xc6\x05\x92\x7f\x67\x98\x72\x76\x75\xb1\x31\x1f\x14\xf9",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\xab\xa3\xf5\x4f\xcc\x3f\xd7\xb7\x23\x73\x51\x6e\x64\xc1\xaa\x6b\xa9\x77\x30\x58\xe6\xd4\xf5\xe9\xa5\xd2\x0d\x35\x42\x65\xda\xf1",
+               NULL,
+       },
+};
+
+static const struct secret server_small_2[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xe7\xf5\x57\x48\x54\x71\xae\xc0\xba\x8d\x12\x90\xc5\x25\xef\xe3\xc7\xea\x39\x09\x24\xe8\x20\x6d\x03\x8d\x80\x1e\xdd\x24\xbb\x5a",
+               (const uint8_t *)"\xf0\x91\x46\x67\xe1\x36\xb5\xd2\x30\x71\xc9\x1d\xcc\x56\xc3\x9d\xee\xfa\x26\xdb\xe4\xe2\x17\xb7\x3d\xb9\x27\x6a\x7c\xa5\xe7\xa9",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               NULL,
+               (const uint8_t *)"\xd8\xdf\x24\xd6\xe1\xdc\x86\x3b\x88\x3d\x2b\xad\x56\xec\x22\xd4\x5c\xaf\xa9\x24\xa3\x90\x20\xa1\xae\x77\x5c\x7d\xef\x3d\xcc\x5b",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\x8d\x02\xe0\xe8\x5f\x9a\xcc\xc7\x8c\x81\x3b\x58\x5f\xa9\xdb\xfd\x98\xb1\x1f\xcc\x3e\x7b\xca\xe7\xef\x05\x4c\x84\x6c\xe1\x11\x25",
+               NULL,
+       },
+};
+
+static const struct secret server_empty_0[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\x24\x24\xaf\xad\xa8\x0e\x40\xc6\xa1\xc3\x05\xff\x5a\xe5\x04\xb9\xc4\xc2\xff\xd6\x2b\x9a\xb8\x43\x85\x78\x92\x1e\x69\x44\x3d\xe2",
+               (const uint8_t *)"\xdc\x47\xf1\x8b\x33\xd6\x08\x26\xa1\xad\xd9\xb0\x81\xee\x32\x01\xb6\xfc\xce\x9a\xa0\x35\xd1\x30\x61\x85\x2d\xff\x3d\xb1\xe5\x49",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               NULL,
+               (const uint8_t *)"\x03\x38\xcf\x43\x68\x90\x01\x7a\xdb\x06\x7d\x92\x08\xcf\x67\x22\x41\xa7\xd3\xe7\x7e\x3a\xaf\x50\xd6\x5c\xaa\xfe\x90\xa4\x87\xa2",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\x5c\x6f\xe8\x8b\xac\x0a\x7b\x04\x76\x9f\xe8\x2a\x7c\x06\x19\x4c\xa7\x51\x5c\xfe\xb9\x31\x25\x0d\x3b\x07\x78\xa9\xdd\x2d\x27\x72",
+               NULL,
+       },
+};
+
+static const struct secret server_empty_1[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\x87\x07\x01\xdc\x13\xdc\xb7\x93\x26\x53\xff\xa4\x2d\x28\xed\xca\xef\x5b\xa7\x94\x17\x26\xdf\x1f\x8c\x7b\x79\x32\x55\x5e\xcb\x79",
+               (const uint8_t *)"\xac\xc2\x07\x48\xba\x3d\x59\x2f\x5f\xce\x79\xda\xa6\x04\x4b\x55\x06\x2c\x9f\x0e\xdf\xda\x42\x51\x9d\x0b\xd9\x39\x4b\x8c\xb2\x7e",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               NULL,
+               (const uint8_t *)"\x73\x16\xe6\x0a\x66\xe1\x81\xd8\x74\xfa\x25\xe3\xf3\x1a\xf2\x4d\x84\xd6\xc6\x7a\x1b\x27\x79\x0a\x09\x9e\xd2\xd4\x1d\xdf\x0f\x53",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\x5f\x8e\xfe\x3e\xa0\x41\x27\x9e\xbb\xba\xf2\xa9\x22\xc6\x06\x58\xb5\xbf\x6e\x29\x3d\x84\x10\x4e\x3f\xe3\xc0\x1f\x7a\x2c\xf5\x21",
+               NULL,
+       },
+};
+
+static const struct secret server_empty_2[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\x87\x07\x01\xdc\x13\xdc\xb7\x93\x26\x53\xff\xa4\x2d\x28\xed\xca\xef\x5b\xa7\x94\x17\x26\xdf\x1f\x8c\x7b\x79\x32\x55\x5e\xcb\x79",
+               (const uint8_t *)"\xac\xc2\x07\x48\xba\x3d\x59\x2f\x5f\xce\x79\xda\xa6\x04\x4b\x55\x06\x2c\x9f\x0e\xdf\xda\x42\x51\x9d\x0b\xd9\x39\x4b\x8c\xb2\x7e",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               NULL,
+               (const uint8_t *)"\x73\x16\xe6\x0a\x66\xe1\x81\xd8\x74\xfa\x25\xe3\xf3\x1a\xf2\x4d\x84\xd6\xc6\x7a\x1b\x27\x79\x0a\x09\x9e\xd2\xd4\x1d\xdf\x0f\x53",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\x5f\x8e\xfe\x3e\xa0\x41\x27\x9e\xbb\xba\xf2\xa9\x22\xc6\x06\x58\xb5\xbf\x6e\x29\x3d\x84\x10\x4e\x3f\xe3\xc0\x1f\x7a\x2c\xf5\x21",
+               NULL,
+       },
+};
+
+static const struct secret server_explicit_0[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\x24\x24\xaf\xad\xa8\x0e\x40\xc6\xa1\xc3\x05\xff\x5a\xe5\x04\xb9\xc4\xc2\xff\xd6\x2b\x9a\xb8\x43\x85\x78\x92\x1e\x69\x44\x3d\xe2",
+               (const uint8_t *)"\xdc\x47\xf1\x8b\x33\xd6\x08\x26\xa1\xad\xd9\xb0\x81\xee\x32\x01\xb6\xfc\xce\x9a\xa0\x35\xd1\x30\x61\x85\x2d\xff\x3d\xb1\xe5\x49",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               NULL,
+               (const uint8_t *)"\x03\x38\xcf\x43\x68\x90\x01\x7a\xdb\x06\x7d\x92\x08\xcf\x67\x22\x41\xa7\xd3\xe7\x7e\x3a\xaf\x50\xd6\x5c\xaa\xfe\x90\xa4\x87\xa2",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\x5c\x6f\xe8\x8b\xac\x0a\x7b\x04\x76\x9f\xe8\x2a\x7c\x06\x19\x4c\xa7\x51\x5c\xfe\xb9\x31\x25\x0d\x3b\x07\x78\xa9\xdd\x2d\x27\x72",
+               NULL,
+       },
+};
+
+static const struct secret server_explicit_1[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_EARLY,
+               32,
+               (const uint8_t *)"\x6f\x16\x97\x8e\x90\x94\x77\x40\x0f\x00\xff\x79\x1c\x15\x20\x19\xeb\xc6\x10\x59\x8f\x92\xac\xab\xe6\xc8\x3c\x12\x30\x94\x91\x12",
+               NULL,
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               NULL,
+               (const uint8_t *)"\xf0\x91\x46\x67\xe1\x36\xb5\xd2\x30\x71\xc9\x1d\xcc\x56\xc3\x9d\xee\xfa\x26\xdb\xe4\xe2\x17\xb7\x3d\xb9\x27\x6a\x7c\xa5\xe7\xa9",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xe7\xf5\x57\x48\x54\x71\xae\xc0\xba\x8d\x12\x90\xc5\x25\xef\xe3\xc7\xea\x39\x09\x24\xe8\x20\x6d\x03\x8d\x80\x1e\xdd\x24\xbb\x5a",
+               NULL,
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               NULL,
+               (const uint8_t *)"\xf8\xa9\xd5\xe6\x18\xbb\xb7\x07\x1d\xb3\x8f\x78\x61\x30\x63\x01\xa5\x49\xc6\x05\x92\x7f\x67\x98\x72\x76\x75\xb1\x31\x1f\x14\xf9",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\xab\xa3\xf5\x4f\xcc\x3f\xd7\xb7\x23\x73\x51\x6e\x64\xc1\xaa\x6b\xa9\x77\x30\x58\xe6\xd4\xf5\xe9\xa5\xd2\x0d\x35\x42\x65\xda\xf1",
+               NULL,
+       },
+};
+
+static const struct secret server_explicit_2[] = {
+       {
+               GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE,
+               32,
+               (const uint8_t *)"\xe7\xf5\x57\x48\x54\x71\xae\xc0\xba\x8d\x12\x90\xc5\x25\xef\xe3\xc7\xea\x39\x09\x24\xe8\x20\x6d\x03\x8d\x80\x1e\xdd\x24\xbb\x5a",
+               (const uint8_t *)"\xf0\x91\x46\x67\xe1\x36\xb5\xd2\x30\x71\xc9\x1d\xcc\x56\xc3\x9d\xee\xfa\x26\xdb\xe4\xe2\x17\xb7\x3d\xb9\x27\x6a\x7c\xa5\xe7\xa9",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               NULL,
+               (const uint8_t *)"\xd8\xdf\x24\xd6\xe1\xdc\x86\x3b\x88\x3d\x2b\xad\x56\xec\x22\xd4\x5c\xaf\xa9\x24\xa3\x90\x20\xa1\xae\x77\x5c\x7d\xef\x3d\xcc\x5b",
+       },
+       {
+               GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
+               32,
+               (const uint8_t *)"\x8d\x02\xe0\xe8\x5f\x9a\xcc\xc7\x8c\x81\x3b\x58\x5f\xa9\xdb\xfd\x98\xb1\x1f\xcc\x3e\x7b\xca\xe7\xef\x05\x4c\x84\x6c\xe1\x11\x25",
+               NULL,
+       },
+};
+
+#endif /* GNUTLS_TESTS_SERVER_SECRETS_H */
index 32b5db30bb13ec355ef658bedfe15b5b3f991812..d26973e4985ecce1c1fe74d59e17b09fcc8c3fc7 100644 (file)
@@ -23,6 +23,7 @@
 #include <config.h>
 #endif
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -53,6 +54,14 @@ int main(void)
 #include "virt-time.h"
 #define MIN(x,y) (((x)<(y))?(x):(y))
 
+#define TRACE_CLIENT 1
+#define TRACE_SERVER 2
+
+/* To reproduce the entries in {client,server}-secrets.h, set this to
+ * either TRACE_CLIENT or TRACE_SERVER.
+ */
+#define TRACE 0
+
 /* This program tests the robustness of record sending with padding.
  */
 
@@ -74,6 +83,8 @@ static void client_log_func(int level, const char *str)
 #define MSG "Hello TLS"
 #define EARLY_MSG "Hello TLS, it's early"
 
+extern unsigned int _gnutls_global_version;
+
 /* This test makes connection 3 times with different ciphersuites:
  * first with TLS_AES_128_GCM_SHA256, then
  * TLS_CHACHA20_POLY1305_SHA256 two times.  The reason for doing this
@@ -86,6 +97,8 @@ static void client_log_func(int level, const char *str)
 
 static const
 gnutls_datum_t hrnd = {(void*)"\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32};
+static const
+gnutls_datum_t hsrnd = {(void*)"\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32};
 
 static int gnutls_rnd_works;
 
@@ -103,7 +116,285 @@ gnutls_rnd(gnutls_rnd_level_t level, void *data, size_t len)
        return 0;
 }
 
-static void client(int sds[], const char *data, size_t size, size_t maxsize)
+#define MAX_SECRET_SIZE 64
+#define MAX_SECRET_COUNT 10
+
+struct secret {
+       gnutls_record_encryption_level_t level;
+       size_t secret_size;
+       const uint8_t *secret_read;
+       const uint8_t *secret_write;
+       uint8_t secret_read_buf[MAX_SECRET_SIZE];
+       uint8_t secret_write_buf[MAX_SECRET_SIZE];
+};
+
+#include "client-secrets.h"
+#include "server-secrets.h"
+
+struct secrets_expected {
+       const struct secret *secrets;
+       size_t count;
+};
+
+#define SIZEOF(array) (sizeof(array) / sizeof(array[0]))
+
+static const struct secrets_expected client_normal[SESSIONS] = {
+       { client_normal_0, SIZEOF(client_normal_0) },
+       { client_normal_1, SIZEOF(client_normal_1) },
+       { client_normal_2, SIZEOF(client_normal_2) },
+};
+
+static const struct secrets_expected client_small[SESSIONS] = {
+       { client_small_0, SIZEOF(client_small_0) },
+       { client_small_1, SIZEOF(client_small_1) },
+       { client_small_2, SIZEOF(client_small_2) },
+};
+
+static const struct secrets_expected client_empty[SESSIONS] = {
+       { client_empty_0, SIZEOF(client_empty_0) },
+       { client_empty_1, SIZEOF(client_empty_1) },
+       { client_empty_2, SIZEOF(client_empty_2) },
+};
+
+static const struct secrets_expected client_explicit[SESSIONS] = {
+       { client_explicit_0, SIZEOF(client_explicit_0) },
+       { client_explicit_1, SIZEOF(client_explicit_1) },
+       { client_explicit_2, SIZEOF(client_explicit_2) },
+};
+
+static const struct secrets_expected server_normal[SESSIONS] = {
+       { server_normal_0, SIZEOF(server_normal_0) },
+       { server_normal_1, SIZEOF(server_normal_1) },
+       { server_normal_2, SIZEOF(server_normal_2) },
+};
+
+static const struct secrets_expected server_small[SESSIONS] = {
+       { server_small_0, SIZEOF(server_small_0) },
+       { server_small_1, SIZEOF(server_small_1) },
+       { server_small_2, SIZEOF(server_small_2) },
+};
+
+static const struct secrets_expected server_empty[SESSIONS] = {
+       { server_empty_0, SIZEOF(server_empty_0) },
+       { server_empty_1, SIZEOF(server_empty_1) },
+       { server_empty_2, SIZEOF(server_empty_2) },
+};
+
+static const struct secrets_expected server_explicit[SESSIONS] = {
+       { server_explicit_0, SIZEOF(server_explicit_0) },
+       { server_explicit_1, SIZEOF(server_explicit_1) },
+       { server_explicit_2, SIZEOF(server_explicit_2) },
+};
+
+struct fixture {
+       const char *name;
+       unsigned int cflags;
+       unsigned int sflags;
+       gnutls_datum_t early_data;
+       size_t max_early_data_size;
+       bool expect_early_data;
+       const struct secrets_expected *client_secrets;
+       const struct secrets_expected *server_secrets;
+};
+
+static const struct fixture fixtures[] = {
+       {
+               .name = "normal",
+               .cflags = 0,
+               .sflags = 0,
+               .early_data = { (uint8_t *)EARLY_MSG, sizeof(EARLY_MSG) },
+               .max_early_data_size = MAX_BUF,
+               .expect_early_data = true,
+               .client_secrets = client_normal,
+               .server_secrets = server_normal,
+       },
+       {
+               .name = "small",
+               .cflags = 0,
+               .sflags = 0,
+               .early_data = { (uint8_t *)EARLY_MSG, sizeof(EARLY_MSG) },
+               .max_early_data_size = 10,
+               .expect_early_data = true,
+               .client_secrets = client_small,
+               .server_secrets = server_small,
+       },
+       {
+               .name = "empty",
+               .cflags = 0,
+               .sflags = 0,
+               .early_data = { NULL, 0 },
+               .max_early_data_size = MAX_BUF,
+               .expect_early_data = false,
+               .client_secrets = client_empty,
+               .server_secrets = server_empty,
+       },
+       {
+               .name = "explicit",
+               .cflags = GNUTLS_ENABLE_EARLY_DATA,
+               .sflags = 0,
+               .early_data = { NULL, 0 },
+               .max_early_data_size = MAX_BUF,
+               .expect_early_data = false,
+               .client_secrets = client_explicit,
+               .server_secrets = server_explicit,
+       },
+};
+
+#if TRACE
+static void
+print_secret(FILE *out, struct secret *secret)
+{
+       const char *level;
+
+       switch (secret->level) {
+       case GNUTLS_ENCRYPTION_LEVEL_INITIAL:
+               level = "GNUTLS_ENCRYPTION_LEVEL_INITIAL";
+               break;
+       case GNUTLS_ENCRYPTION_LEVEL_EARLY:
+               level = "GNUTLS_ENCRYPTION_LEVEL_EARLY";
+               break;
+       case GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE:
+               level = "GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE";
+               break;
+       case GNUTLS_ENCRYPTION_LEVEL_APPLICATION:
+               level = "GNUTLS_ENCRYPTION_LEVEL_APPLICATION";
+               break;
+       }
+
+       fprintf(out, "\t\t%s,\n\t\t%zu,\n", level, secret->secret_size);
+       if (secret->secret_read) {
+               size_t i;
+
+               fputs("\t\t(const uint8_t *)\"", out);
+               for (i = 0; i < secret->secret_size; i++) {
+                       fprintf(out, "\\x%.2x", secret->secret_read[i]);
+               }
+               fputs("\",\n", out);
+       } else {
+               fputs("\t\tNULL,\n", out);
+       }
+       if (secret->secret_write) {
+               size_t i;
+
+               fputs("\t\t(const uint8_t *)\"", out);
+               for (i = 0; i < secret->secret_size; i++) {
+                       fprintf(out, "\\x%.2x", secret->secret_write[i]);
+               }
+               fputs("\",\n", out);
+       } else {
+               fputs("\t\tNULL,\n", out);
+       }
+}
+
+static void
+print_secrets(FILE *out, const char *side, const char *name, int t,
+             struct secret *secrets, size_t count)
+{
+       size_t i;
+
+       fprintf(out, "static const struct secret %s_%s_%d[] = {\n",
+               side, name, t);
+       for (i = 0; i < count; i++) {
+               fputs("\t{\n", out);
+               print_secret(out, &secrets[i]);
+               fputs("\t},\n", out);
+       }
+       fputs("};\n\n", out);
+}
+#endif
+
+static void
+check_secrets(const struct secret *secrets, size_t count,
+             const struct secrets_expected *expected)
+{
+       size_t i;
+
+       if (count != expected->count) {
+               fail("unexpected number of secrets: %zu != %zu\n",
+                    count, expected->count);
+       }
+
+       for (i = 0; i < count; i++) {
+               if (secrets[i].level != expected->secrets[i].level) {
+                       fail("unexpected secret level: %d != %d\n",
+                            secrets[i].level, expected->secrets[i].level);
+               }
+               if (secrets[i].secret_size != expected->secrets[i].secret_size) {
+                       fail("unexpected secret size: %zu != %zu\n",
+                            secrets[i].secret_size, expected->secrets[i].secret_size);
+               }
+               if ((secrets[i].secret_read == NULL) !=
+                   (expected->secrets[i].secret_read == NULL)) {
+                       fail("unexpected secret for read: %p != %p\n",
+                            secrets[i].secret_read, expected->secrets[i].secret_read);
+               }
+               if (expected->secrets[i].secret_read &&
+                   memcmp(secrets[i].secret_read,
+                          expected->secrets[i].secret_read,
+                          secrets[i].secret_size) != 0) {
+                       fail("unexpected secret for read\n");
+               }
+               if ((secrets[i].secret_write == NULL) !=
+                   (expected->secrets[i].secret_write == NULL)) {
+                       fail("unexpected secret for write: %p != %p\n",
+                            secrets[i].secret_write, expected->secrets[i].secret_write);
+               }
+               if (expected->secrets[i].secret_write &&
+                   memcmp(secrets[i].secret_write,
+                          expected->secrets[i].secret_write,
+                          secrets[i].secret_size) != 0) {
+                       fail("unexpected secret for write\n");
+               }
+       }
+}
+
+struct callback_data {
+       int t;
+       size_t secret_callback_called;
+       struct secret secrets[MAX_SECRET_COUNT];
+};
+
+static int
+secret_callback(gnutls_session_t session,
+               gnutls_record_encryption_level_t level,
+               const void *secret_read,
+               const void *secret_write,
+               size_t secret_size)
+{
+       struct callback_data *data = gnutls_session_get_ptr(session);
+       struct secret *secret = &data->secrets[data->secret_callback_called];
+
+       if (data->t == 0) {
+               if (level == GNUTLS_ENCRYPTION_LEVEL_EARLY) {
+                       fail("early secret is set on initial connection\n");
+               }
+       }
+
+       if (secret_size > MAX_SECRET_SIZE) {
+               fail("secret is too long\n");
+       }
+
+       secret->secret_size = secret_size;
+       secret->level = level;
+       if (secret_read) {
+               memcpy(secret->secret_read_buf, secret_read, secret_size);
+               secret->secret_read = secret->secret_read_buf;
+       }
+       if (secret_write) {
+               memcpy(secret->secret_write_buf, secret_write, secret_size);
+               secret->secret_write = secret->secret_write_buf;
+       }
+
+       data->secret_callback_called++;
+       if (data->secret_callback_called > MAX_SECRET_COUNT) {
+               fail("secret func called too many times");
+       }
+
+       return 0;
+}
+
+static void
+client(int sds[], const struct fixture *fixture)
 {
        int ret;
        char buffer[MAX_BUF + 1];
@@ -112,37 +403,47 @@ static void client(int sds[], const char *data, size_t size, size_t maxsize)
        int t;
        gnutls_datum_t session_data = {NULL, 0};
 
+       global_init();
+
+       /* date --date='TZ="UTC" 2021-04-29' +%s */
+       virt_time_init_at(1619654400);
+
        if (debug) {
                gnutls_global_set_log_function(client_log_func);
                gnutls_global_set_log_level(7);
        }
 
-       /* Generate the same ob_ticket_age value, which affects the
-        * binder calculation.
-        */
-       virt_time_init();
-
        gnutls_certificate_allocate_credentials(&x509_cred);
 
        for (t = 0; t < SESSIONS; t++) {
                int sd = sds[t];
+               struct callback_data callback_data;
 
-               assert(gnutls_init(&session, GNUTLS_CLIENT)>=0);
+               assert(gnutls_init(&session, GNUTLS_CLIENT|fixture->cflags)>=0);
                assert(gnutls_priority_set_direct(session, t == 0 ? TLS13_AES_128_GCM : TLS13_CHACHA20_POLY1305, NULL)>=0);
 
                gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
 
                gnutls_transport_set_int(session, sd);
+               assert(gnutls_handshake_set_random(session, &hrnd) >= 0);
+
+               memset(&callback_data, 0, sizeof(callback_data));
+               callback_data.t = t;
+               gnutls_session_set_ptr(session, &callback_data);
+               gnutls_handshake_set_secret_function(session, secret_callback);
 
                if (t > 0) {
                        assert(gnutls_session_set_data(session, session_data.data, session_data.size) >= 0);
                        /* The server should have advertised the same maximum. */
-                       if (gnutls_record_get_max_early_data_size(session) != maxsize)
+                       if (gnutls_record_get_max_early_data_size(session) !=
+                           fixture->max_early_data_size)
                                fail("client: max_early_data_size mismatch %d != %d\n",
                                     (int) gnutls_record_get_max_early_data_size(session),
-                                    (int) maxsize);
-                       assert(gnutls_record_send_early_data(session, data, MIN(size, maxsize)) >= 0);
-                       assert(gnutls_handshake_set_random(session, &hrnd) >= 0);
+                                    (int) fixture->max_early_data_size);
+                       assert(gnutls_record_send_early_data(session,
+                                                            fixture->early_data.data,
+                                                            MIN(fixture->early_data.size,
+                                                                fixture->max_early_data_size)) >= 0);
                }
 
                /* Perform the TLS handshake
@@ -154,14 +455,26 @@ static void client(int sds[], const char *data, size_t size, size_t maxsize)
                while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
 
                if (ret < 0) {
-                       fail("client: Handshake failed\n");
-                       gnutls_perror(ret);
-                       exit(1);
+                       fail("client: Handshake failed: %s\n",
+                            gnutls_strerror(ret));
                } else {
                        if (debug)
                                success("client: Handshake was completed\n");
                }
 
+               if (!gnutls_rnd_works) {
+                       success("client: gnutls_rnd() could not be overridden\n");
+               } else {
+#if TRACE == TRACE_CLIENT
+                       print_secrets(stderr, "client", fixture->name, t,
+                                     callback_data.secrets,
+                                     callback_data.secret_callback_called);
+#endif
+                       check_secrets(callback_data.secrets,
+                                     callback_data.secret_callback_called,
+                                     &fixture->client_secrets[t]);
+               }
+
                if (t == 0) {
                        /* get the session data size */
                        ret =
@@ -189,7 +502,6 @@ static void client(int sds[], const char *data, size_t size, size_t maxsize)
                        goto end;
                } else if (ret < 0) {
                        fail("client: Error: %s\n", gnutls_strerror(ret));
-                       goto end;
                }
 
                gnutls_bye(session, GNUTLS_SHUT_WR);
@@ -202,6 +514,8 @@ static void client(int sds[], const char *data, size_t size, size_t maxsize)
  end:
        gnutls_free(session_data.data);
        gnutls_certificate_free_credentials(x509_cred);
+
+       gnutls_global_deinit();
 }
 
 
@@ -256,7 +570,8 @@ storage_clear(struct storage_st *storage)
        storage->num_entries = 0;
 }
 
-static void server(int sds[], const char *data, size_t size, size_t maxsize)
+static void
+server(int sds[], const struct fixture *fixture)
 {
        int ret;
        char buffer[MAX_BUF + 1];
@@ -270,6 +585,10 @@ static void server(int sds[], const char *data, size_t size, size_t maxsize)
        /* this must be called once in the program
         */
        global_init();
+
+       /* date --date='TZ="UTC" 2021-04-29' +%s */
+       virt_time_init_at(1619654400);
+
        memset(buffer, 0, sizeof(buffer));
        memset(&storage, 0, sizeof(storage));
 
@@ -294,6 +613,7 @@ static void server(int sds[], const char *data, size_t size, size_t maxsize)
 
        for (t = 0; t < SESSIONS; t++) {
                int sd = sds[t];
+               struct callback_data callback_data;
 
                assert(gnutls_init(&session, GNUTLS_SERVER|GNUTLS_ENABLE_EARLY_DATA)>=0);
 
@@ -310,10 +630,16 @@ static void server(int sds[], const char *data, size_t size, size_t maxsize)
                 * until max_early_data_size without decryption
                 */
                if (t < 2)
-                       (void) gnutls_record_set_max_early_data_size(session, maxsize);
+                       (void) gnutls_record_set_max_early_data_size(session, fixture->max_early_data_size);
 
+               assert(gnutls_handshake_set_random(session, &hsrnd) >= 0);
                gnutls_transport_set_int(session, sd);
 
+               memset(&callback_data, 0, sizeof(callback_data));
+               callback_data.t = t;
+               gnutls_session_set_ptr(session, &callback_data);
+               gnutls_handshake_set_secret_function(session, secret_callback);
+
                do {
                        ret = gnutls_handshake(session);
                }
@@ -323,7 +649,6 @@ static void server(int sds[], const char *data, size_t size, size_t maxsize)
                        gnutls_deinit(session);
                        fail("server: Handshake has failed (%s)\n\n",
                             gnutls_strerror(ret));
-                       return;
                }
                if (debug)
                        success("server: Handshake was completed\n");
@@ -332,38 +657,62 @@ static void server(int sds[], const char *data, size_t size, size_t maxsize)
                        if (!gnutls_session_is_resumed(session)) {
                                fail("server: session_is_resumed error (%d)\n", t);
                        }
+               }
+
+               if (!gnutls_rnd_works) {
+                       success("server: gnutls_rnd() could not be overridden\n");
+                       goto skip_early_data;
+               }
+
+#if TRACE == TRACE_SERVER
+               print_secrets(stderr, "server", fixture->name, t,
+                             callback_data.secrets,
+                             callback_data.secret_callback_called);
+#endif
+               check_secrets(callback_data.secrets,
+                             callback_data.secret_callback_called,
+                             &fixture->server_secrets[t]);
+
+               /* as we reuse the same ticket twice, expect
+                * early data only on the first resumption */
+               if (t == 1) {
+                       if (fixture->expect_early_data &&
+                           !(gnutls_session_get_flags(session) & GNUTLS_SFLAGS_EARLY_DATA)) {
+                               fail("server: early data is not received (%d)\n",
+                                    t);
+                       }
 
-                       /* as we reuse the same ticket twice, expect
-                        * early data only on the first resumption */
-                       if (t == 1) {
-                               if (gnutls_rnd_works) {
-                                       if (!(gnutls_session_get_flags(session) & GNUTLS_SFLAGS_EARLY_DATA)) {
-                                               fail("server: early data is not received (%d)\n", t);
+                       ret = gnutls_record_recv_early_data(session, buffer, sizeof(buffer));
+                       if (ret < 0) {
+                               if (fixture->early_data.size == 0 ||
+                                   fixture->max_early_data_size == 0) {
+                                       if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+                                               fail("server: unexpected error code when retrieving empty early data: %s\n",
+                                                    gnutls_strerror(ret));
                                        }
                                } else {
-                                       success("server: gnutls_rnd() could not be overridden, skip checking replay (%d)\n", t);
-                               }
-
-                               ret = gnutls_record_recv_early_data(session, buffer, sizeof(buffer));
-                               if (ret < 0) {
                                        fail("server: failed to retrieve early data: %s\n",
                                             gnutls_strerror(ret));
                                }
-
-                               if ((size_t) ret != MIN(size, maxsize) ||
-                                   memcmp(buffer, data, ret))
-                                       fail("server: early data mismatch\n");
                        } else {
-                               if (gnutls_rnd_works) {
-                                       if (gnutls_session_get_flags(session) & GNUTLS_SFLAGS_EARLY_DATA) {
-                                               fail("server: early data is not rejected (%d)\n", t);
-                                       }
-                               } else {
-                                       success("server: gnutls_rnd() could not be overridden, skip checking replay (%d)\n", t);
+                               if (fixture->early_data.size == 0 ||
+                                   fixture->max_early_data_size == 0) {
+                                       fail("server: unexpected early data received: %d\n",
+                                            ret);
+                               } else if ((size_t) ret != MIN(fixture->early_data.size,
+                                                              fixture->max_early_data_size) ||
+                                          memcmp(buffer, fixture->early_data.data, ret)) {
+                                       fail("server: early data mismatch\n");
                                }
                        }
+               } else if (t == 2) {
+                       if (fixture->expect_early_data &&
+                           gnutls_session_get_flags(session) & GNUTLS_SFLAGS_EARLY_DATA) {
+                               fail("server: early data is not rejected (%d)\n", t);
+                       }
                }
 
+       skip_early_data:
                /* see the Getting peer's information example */
                /* print_info(session); */
 
@@ -378,8 +727,7 @@ static void server(int sds[], const char *data, size_t size, size_t maxsize)
                                break;
                        } else if (ret < 0) {
                                kill(child, SIGTERM);
-                               fail("server: Received corrupted data(%d). Closing...\n", ret);
-                               break;
+                               fail("server: Error: %s\n", gnutls_strerror(ret));
                        } else if (ret > 0) {
                                /* echo data back to the client
                                 */
@@ -404,17 +752,20 @@ static void server(int sds[], const char *data, size_t size, size_t maxsize)
 
        gnutls_certificate_free_credentials(x509_cred);
 
+       gnutls_global_deinit();
+
        if (debug)
                success("server: finished\n");
 }
 
 static void
-start(const char *data, size_t size, size_t maxsize)
+start(const struct fixture *fixture)
 {
        int client_sds[SESSIONS], server_sds[SESSIONS];
        int i;
        int ret;
 
+       _gnutls_global_version = 0x030607;
        signal(SIGCHLD, SIG_IGN);
        signal(SIGPIPE, SIG_IGN);
 
@@ -435,32 +786,38 @@ start(const char *data, size_t size, size_t maxsize)
        if (child < 0) {
                perror("fork");
                fail("fork");
-               exit(1);
        }
 
        if (child) {
                /* parent */
                for (i = 0; i < SESSIONS; i++)
                        close(client_sds[i]);
-               server(server_sds, data, size, maxsize);
+               server(server_sds, fixture);
                kill(child, SIGTERM);
        } else {
                for (i = 0; i < SESSIONS; i++)
                        close(server_sds[i]);
-               client(client_sds, data, size, maxsize);
+               client(client_sds, fixture);
                exit(0);
        }
 }
 
 void doit(void)
 {
+       size_t i;
+
        /* TLS_CHACHA20_POLY1305_SHA256 is needed for this test */
        if (gnutls_fips140_mode_enabled()) {
                exit(77);
        }
 
-       start(EARLY_MSG, sizeof(EARLY_MSG), MAX_BUF);
-       start(EARLY_MSG, sizeof(EARLY_MSG), 10);
+       for (i = 0; i < SIZEOF(fixtures); i++) {
+               start(&fixtures[i]);
+       }
+
+       if (!gnutls_rnd_works) {
+               exit(77);
+       }
 }
 
 #endif                         /* _WIN32 */