@@ -29,6 +29,7 @@ before_install:
- sudo apt-get install -y autoconf-archive
- sudo apt-get install -y linux-headers-$(uname -r)
- sudo apt-get install -y libmbedtls-dev
+ - sudo apt-get install -y libcmocka-dev
script:
- sudo ln -sf /usr/lib/x86_64-linux-gnu/pkgconfig/lua5.2.pc /usr/lib/x86_64-linux-gnu/pkgconfig/lua.pc
@@ -75,4 +76,5 @@ script:
- make
- sudo make install
- cd ..
- - for i in configs/*;do echo $i;make `basename $i` && make || exit 1;done
+ - sudo ldconfig
+ - for i in configs/*;do echo $i;make `basename $i` && make || exit 1;make test || exit 1;done
@@ -476,9 +476,9 @@ PHONY += suricatta-tests
suricatta-tests: FORCE
$(Q)$(MAKE) $(build)=suricatta/test SWOBJS="$(swupdate-objs)" SWLIBS="$(swupdate-libs)" LDLIBS="$(LDLIBS)" tests
-PHONY += corelib-tests
-corelib-tests: FORCE
- $(Q)$(MAKE) $(build)=corelib/test SWOBJS="$(swupdate-objs)" SWLIBS="$(swupdate-libs)" LDLIBS="$(LDLIBS)" tests
+PHONY += test
+test:
+ $(Q)$(MAKE) $(build)=test SWOBJS="$(swupdate-objs)" SWLIBS="$(swupdate-libs)" LDLIBS="$(LDLIBS)" tests
# The actual objects are generated when descending,
# make sure no implicit rule kicks in
similarity index 70%
rename from corelib/test/Makefile
rename to test/Makefile
@@ -16,6 +16,10 @@
## Foundation, Inc.
tests-$(CONFIG_ENCRYPTED_IMAGES) += test_crypt
+tests-$(CONFIG_HASH_VERIFY) += test_hash
+ifeq ($(CONFIG_SIGALG_RAWRSA),y)
+tests-$(CONFIG_SIGNED_IMAGES) += test_verify
+endif
ccflags-y += -I$(src)/../
@@ -45,7 +49,7 @@ EXECUTE_TEST = echo "RUN $(subst $(obj)/,,$(var))"; CMOCKA_MESSAGE_OUTPUT=TAP $(
PHONY += default
default:
- $(info please run 'make corelib-tests' in swupdate main directory)
+ $(info please run 'make test' in swupdate main directory)
PHONY += tests
ifneq "$(tests-y)" ""
@@ -57,8 +61,27 @@ tests:
@:
endif
-$(obj)/%.lnk: $(objtree)/core/built-in.o
+$(obj)/%.lnk: $(obj)/%.o $(objtree)/core/built-in.o
$(Q)strip -N main -o $(objtree)/core/built-in.o.tmp $(objtree)/core/built-in.o
$(Q)$(call cmd,linktestexe)
+DATADIR := test/data
+
+$(obj)/test_verify.o: $(DATADIR)/signature $(DATADIR)/signing-pubkey.pem
+
+.INTERMEDIATE: $(DATADIR)/signature
+$(DATADIR)/signature: $(DATADIR)/to-be-signed $(DATADIR)/signing-secret.pem
+ $(if $(Q),@echo " SIGN $@")
+ $(Q)openssl dgst -sha256 -sign $(DATADIR)/signing-secret.pem $(DATADIR)/to-be-signed > $@
+
+.INTERMEDIATE: $(DATADIR)/signing-pubkey.pem
+$(DATADIR)/signing-pubkey.pem: $(DATADIR)/signing-secret.pem
+ $(if $(Q),@echo " EXPORT $@")
+ $(Q)openssl rsa -in $< -out $@ -outform PEM -pubout 2>/dev/null
+
+.INTERMEDIATE: $(DATADIR)/signing-secret.pem
+$(DATADIR)/signing-secret.pem:
+ $(if $(Q),@echo " GEN $@")
+ $(Q)openssl genrsa -out $@ 2>/dev/null
+
.PHONY: $(PHONY)
new file mode 100644
@@ -0,0 +1 @@
+abc
similarity index 100%
rename from corelib/test/test_crypt.c
rename to test/test_crypt.c
new file mode 100644
@@ -0,0 +1,124 @@
+/*
+ * This program 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 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdarg.h>
+#include <cmocka.h>
+#include <string.h>
+
+#include "sslapi.h"
+#include "util.h"
+
+struct testvector {
+ const char *input;
+ const char *sha1;
+ const char *sha256;
+};
+
+// https://www.di-mgt.com.au/sha_testvectors.html
+static const struct testvector testvectors[] = {
+ {
+ .input = "abc",
+ .sha1 = "a9993e364706816aba3e25717850c26c9cd0d89d",
+ .sha256 = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
+ },
+ {
+ .input = "",
+ .sha1 = "da39a3ee5e6b4b0d3255bfef95601890afd80709",
+ .sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ },
+ {
+ .input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ .sha1 = "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
+ .sha256 = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
+ },
+ {
+ .input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+ .sha1 = "a49b2446a02c645bf419f995b67091253a04a259",
+ .sha256 = "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1",
+ },
+};
+
+static void hex2bin(unsigned char *dest, const unsigned char *source)
+{
+ unsigned int val;
+ for (unsigned int i = 0; i < strlen((const char *)source); i += 2) {
+ val = from_ascii((const char *)&source[i], 2, LG_16);
+ dest[i / 2] = val;
+ }
+}
+
+static void do_concrete_hash(const char* algo, const char* input, const char* expected_hex)
+{
+ int error;
+ uint8_t result[32] = {0};
+ unsigned len = 0;
+ uint8_t expected_bin[32] = {0};
+ struct swupdate_digest *dgst;
+
+ dgst = swupdate_HASH_init(algo);
+ assert_non_null(dgst);
+ error = swupdate_HASH_update(dgst, (uint8_t *)input, strlen(input));
+ assert_true(!error);
+
+ error = swupdate_HASH_final(dgst, result, &len);
+ assert_int_equal(error, 1);
+ assert_int_equal(len, strlen(expected_hex) / 2);
+
+ swupdate_HASH_cleanup(dgst);
+
+ hex2bin(expected_bin, (uint8_t *)expected_hex);
+ error = swupdate_HASH_compare(expected_bin, result);
+ assert_true(!error);
+}
+
+static void do_hash(const struct testvector *vector)
+{
+ do_concrete_hash("sha1", vector->input, vector->sha1);
+ do_concrete_hash("sha256", vector->input, vector->sha256);
+}
+
+static void test_hash_vectors(void **state)
+{
+ unsigned i;
+
+ (void)state;
+
+ for (i = 0; i < sizeof(testvectors) / sizeof(testvectors[0]); ++i) {
+ do_hash(testvectors + i);
+ }
+}
+
+static void test_hash_compare(void **state)
+{
+ (void)state;
+
+ static const uint8_t a[32] = {0};
+ static const uint8_t b[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
+
+ assert_int_equal(swupdate_HASH_compare(a, a), 0);
+ assert_int_equal(swupdate_HASH_compare(a, b), -1);
+}
+
+int main(void)
+{
+ static const struct CMUnitTest hash_tests[] = {
+ cmocka_unit_test(test_hash_compare),
+ cmocka_unit_test(test_hash_vectors),
+ };
+ return cmocka_run_group_tests_name("hash", hash_tests, NULL, NULL);
+}
new file mode 100644
@@ -0,0 +1,50 @@
+/*
+ * This program 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 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ */
+
+#include <setjmp.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <cmocka.h>
+
+#include "sslapi.h"
+#include "swupdate.h"
+
+#define DATADIR "test/data/"
+
+static void test_verify_pkcs15(void **state)
+{
+ int error;
+ struct swupdate_cfg config;
+
+ (void)state;
+
+ config.dgst = NULL;
+ error = swupdate_dgst_init(&config, DATADIR "signing-pubkey.pem");
+ assert_int_equal(error, 0);
+
+ error = swupdate_verify_file(config.dgst, DATADIR "signature",
+ DATADIR "to-be-signed", NULL);
+ assert_int_equal(error, 0);
+}
+
+int main(void)
+{
+ swupdate_crypto_init();
+ static const struct CMUnitTest verify_tests[] = {
+ cmocka_unit_test(test_verify_pkcs15),
+ };
+ return cmocka_run_group_tests_name("verify", verify_tests, NULL, NULL);
+}