summaryrefslogtreecommitdiffstats
path: root/test/unit/keys.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/unit/keys.c')
-rw-r--r--test/unit/keys.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/test/unit/keys.c b/test/unit/keys.c
new file mode 100644
index 0000000..aa5e649
--- /dev/null
+++ b/test/unit/keys.c
@@ -0,0 +1,173 @@
+/*
+ **********************************************************************
+ * Copyright (C) Miroslav Lichvar 2017
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ **********************************************************************
+ */
+
+#include <config.h>
+#include "test.h"
+
+#if defined(FEAT_NTP) || defined(FEAT_CMDMON)
+
+#include <keys.c>
+
+#define KEYS 100
+#define KEYFILE "keys.test-keys"
+
+static
+uint32_t write_random_key(FILE *f)
+{
+ const char *type, *prefix;
+ char key[128];
+ uint32_t id;
+ int i, length;
+
+ length = random() % sizeof (key) + 1;
+ length = MAX(length, 4);
+ prefix = random() % 2 ? "HEX:" : "";
+
+ switch (random() % 8) {
+#ifdef FEAT_SECHASH
+ case 0:
+ type = "SHA1";
+ break;
+ case 1:
+ type = "SHA256";
+ break;
+ case 2:
+ type = "SHA384";
+ break;
+ case 3:
+ type = "SHA512";
+ break;
+#endif
+#ifdef HAVE_CMAC
+ case 4:
+ type = "AES128";
+ length = prefix[0] == '\0' ? 8 : 16;
+ break;
+ case 5:
+ type = "AES256";
+ length = prefix[0] == '\0' ? 16 : 32;
+ break;
+#endif
+ case 6:
+ type = "MD5";
+ break;
+ default:
+ type = "";
+ }
+
+ UTI_GetRandomBytes(&id, sizeof (id));
+ UTI_GetRandomBytes(key, length);
+
+ fprintf(f, "%u %s %s", id, type, prefix);
+ for (i = 0; i < length; i++)
+ fprintf(f, "%02hhX", key[i]);
+ fprintf(f, "\n");
+
+ return id;
+}
+
+static void
+generate_key_file(const char *name, uint32_t *keys)
+{
+ FILE *f;
+ int i;
+
+ f = fopen(name, "w");
+ TEST_CHECK(f);
+ for (i = 0; i < KEYS; i++)
+ keys[i] = write_random_key(f);
+ fclose(f);
+}
+
+void
+test_unit(void)
+{
+ int i, j, data_len, auth_len, type, bits;
+ uint32_t keys[KEYS], key;
+ unsigned char data[100], auth[MAX_HASH_LENGTH];
+ char conf[][100] = {
+ "keyfile "KEYFILE
+ };
+
+ CNF_Initialise(0, 0);
+ for (i = 0; i < sizeof conf / sizeof conf[0]; i++)
+ CNF_ParseLine(NULL, i + 1, conf[i]);
+
+ generate_key_file(KEYFILE, keys);
+ KEY_Initialise();
+
+ for (i = 0; i < 100; i++) {
+ DEBUG_LOG("iteration %d", i);
+
+ if (i) {
+ generate_key_file(KEYFILE, keys);
+ KEY_Reload();
+ }
+
+ UTI_GetRandomBytes(data, sizeof (data));
+
+ for (j = 0; j < KEYS; j++) {
+ TEST_CHECK(KEY_KeyKnown(keys[j]));
+ TEST_CHECK(KEY_GetAuthLength(keys[j]) >= 16);
+
+ data_len = random() % (sizeof (data) + 1);
+ auth_len = KEY_GenerateAuth(keys[j], data, data_len, auth, sizeof (auth));
+ TEST_CHECK(auth_len >= 16);
+
+ TEST_CHECK(KEY_CheckAuth(keys[j], data, data_len, auth, auth_len, auth_len));
+
+ if (j > 0 && keys[j - 1] != keys[j])
+ TEST_CHECK(!KEY_CheckAuth(keys[j - 1], data, data_len, auth, auth_len, auth_len));
+
+ auth_len = random() % auth_len + 1;
+ if (auth_len < MAX_HASH_LENGTH)
+ auth[auth_len]++;
+ TEST_CHECK(KEY_CheckAuth(keys[j], data, data_len, auth, auth_len, auth_len));
+
+ auth[auth_len - 1]++;
+ TEST_CHECK(!KEY_CheckAuth(keys[j], data, data_len, auth, auth_len, auth_len));
+
+ TEST_CHECK(KEY_GetKeyInfo(keys[j], &type, &bits));
+ TEST_CHECK(type > 0 && bits > 0);
+ }
+
+ for (j = 0; j < 1000; j++) {
+ UTI_GetRandomBytes(&key, sizeof (key));
+ if (KEY_KeyKnown(key))
+ continue;
+ TEST_CHECK(!KEY_GetKeyInfo(key, &type, &bits));
+ TEST_CHECK(!KEY_GenerateAuth(key, data, data_len, auth, sizeof (auth)));
+ TEST_CHECK(!KEY_CheckAuth(key, data, data_len, auth, auth_len, auth_len));
+ }
+ }
+
+ unlink(KEYFILE);
+
+ KEY_Finalise();
+ CNF_Finalise();
+ HSH_Finalise();
+}
+#else
+void
+test_unit(void)
+{
+ TEST_REQUIRE(0);
+}
+#endif