]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
regress: add a crypto-unittest
authorAlain Spineux <alain@baculasystems.com>
Mon, 19 Sep 2022 12:19:11 +0000 (14:19 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 14 Sep 2023 11:56:59 +0000 (13:56 +0200)
- the main goal is to learn how the use the crypt_* function
- for now test only signature part

bacula/src/tools/Makefile.in
bacula/src/tools/crypto_test.c [new file with mode: 0644]
regress/DartTestfile.txt.in
regress/tests/crypto-unittests [new file with mode: 0755]

index 3e17f4d0be80f223608b1cdea9ed32c5e56b9a68..71e5f135bbb28a0900adaa27e6a9f85080880ab9 100644 (file)
@@ -46,7 +46,7 @@ TOOLS = $(@DIR_TOOLS@)
 INSNODIRTOOLS = bsmtp
 INSDIRTOOLS = bsmtp dbcheck bwild bregex
 INSTOOLS = $(INS@DIR_TOOLS@) @TOOLS_INSTALL@
-INSTTESTS = breaddir_test bpipe_test tags_test xattr_append_test
+INSTTESTS = breaddir_test bpipe_test tags_test xattr_append_test crypto_test
 
 .SUFFIXES:     .c .o
 .PHONY:
@@ -96,6 +96,9 @@ bpipe_test: bpipe_test.o ../lib/unittests.o
        $(LIBTOOL_LINK) $(CXX) $(LDFLAGS)  -L../lib -o $@ bpipe_test.o ../lib/unittests.o -lbac $(DLIB) $(LIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS)
        $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) $@ $(DESTDIR)$(sbindir)/
 
+crypto_test: crypto_test.o ../lib/unittests.o
+       $(LIBTOOL_LINK) $(CXX) $(LDFLAGS)  -L../lib -o $@ crypto_test.o ../lib/unittests.o -lbac $(DLIB) $(LIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS)
+
 bsparse: bsparse.c
        $(CXX) -Wall -o $@ bsparse.c
 
diff --git a/bacula/src/tools/crypto_test.c b/bacula/src/tools/crypto_test.c
new file mode 100644 (file)
index 0000000..83d0eee
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2000-2023 Kern Sibbald
+
+   The original author of Bacula is Kern Sibbald, with contributions
+   from many others, a complete list can be found in the file AUTHORS.
+
+   You may use this file and others of this release according to the
+   license defined in the LICENSE file, which includes the Affero General
+   Public License, v3.0 ("AGPLv3") and some additional permissions and
+   terms pursuant to its AGPLv3 Section 7.
+
+   This notice must be preserved when any source code is
+   conveyed and/or propagated.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+
+/* the goal is to show how to use the functions in lib/crypto.c
+ * to sign a stream of data
+ */
+
+#include "bacula.h"
+#include "../lib/unittests.h"
+
+/* the goal is to show how to use the functions in lib/crypto.c
+ * to sign a stream of data and verify the signature
+ * the code come
+ */
+int test_signature()
+{
+   JCR *jcr = NULL;
+   X509_KEYPAIR *pki_keypair_pub;
+   X509_KEYPAIR *pki_keypair_priv; // these two keypaire could only be one
+   uint8_t data[65536];
+   uint8_t mysignature[65536];
+   uint8_t mysignature2[65536];
+   int ret;
+   log("Test signatures");
+
+   int len=sizeof(data);
+   // Find the keys and certificates
+   const char *tmp = getenv("tmp");
+   if (!tmp) {
+      tmp="/tmp";
+   } else {
+      printf("Use tmp=%s\n", tmp);
+   }
+
+   POOL_MEM filename(PM_FNAME);
+   struct stat statbuf;
+   Mmsg(filename, "%s/cryptokeypair.pem", tmp);
+
+   if (stat(filename.c_str(), &statbuf)!=0) {
+      fprintf(stderr, "crypto pair not found: %s\n", filename.c_str());
+      ok(false, "crypto pair not found");
+      return 1;
+   }
+   // load the keypair
+   pki_keypair_pub = crypto_keypair_new();
+   pki_keypair_priv = crypto_keypair_new();
+   // load public certificate
+   ret = crypto_keypair_load_cert(pki_keypair_pub, filename.c_str());
+   ok(ret, "load public certificate");
+
+   // load public certificate and ist private key into the other keypair
+   ret = crypto_keypair_load_cert(pki_keypair_priv, filename.c_str()); // needed too initialize keyid
+   ret = crypto_keypair_load_key(pki_keypair_priv, filename.c_str(), NULL, NULL);
+   ok(ret, "load private key");
+
+   // in crypto_setup_digests(bctx_t &bctx)
+   crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA256;
+   DIGEST *signing_digest = crypto_digest_new(jcr, signing_algorithm);
+   ok(signing_digest != NULL, "signature digest initialization");
+
+   // call crypto_digest_update()
+   int cont = 1;
+   for (int i=0; cont != 0 && i<1000; i++) {
+      cont = crypto_digest_update(signing_digest, data, len);
+   }
+   ok(cont!=0, "update");
+
+   // in crypto_terminate_digests(bctx_t &bctx)
+   SIGNATURE *sig = crypto_sign_new(jcr);
+   ok(sig != NULL, "crypto_sign_new");
+
+   ret = crypto_sign_add_signer(sig, signing_digest, pki_keypair_priv);
+   ok(ret, "An error occurred while adding signer the stream");
+
+   // Get signature size
+   uint32_t size = 0;
+   ret = crypto_sign_encode(sig, NULL, &size); // this is mendatory
+   ok(ret, "retrieving the size of the signature");
+
+   ok(size<=sizeof(mysignature), "check signature size");
+
+   ret = crypto_sign_encode(sig, mysignature, &size);
+   ok(ret, "signe the stream");
+
+   // decode the "encoded" signature
+   SIGNATURE *sig2 = crypto_sign_decode(jcr, mysignature, size);
+   ok(sig2 != NULL, "decode the signature");
+
+   // verify_signature(r_ctx &rctx)
+   // reuse the same digest (the lazy way)
+   crypto_error_t crypto_err = crypto_sign_verify(sig2, pki_keypair_pub, signing_digest);
+   ok(crypto_err == CRYPTO_ERROR_NONE, "crypto_sign_verify");
+   {
+      // No do the same calculation on another piece of data and check
+      // that the new digest dont match the previous signature
+      DIGEST *signing_digest = crypto_digest_new(jcr, signing_algorithm);
+      const char *lorem_ipsum = "Lorem Ipsum";
+      int upd = crypto_digest_update(signing_digest, (const uint8_t *)lorem_ipsum, strlen(lorem_ipsum));
+      SIGNATURE *sig = crypto_sign_new(jcr);
+      int ret = crypto_sign_add_signer(sig, signing_digest, pki_keypair_priv);
+      uint32_t size = 0;
+      crypto_sign_encode(sig, NULL, &size); // this is required to initialize size=~122
+      int enc = crypto_sign_encode(sig, mysignature2, &size);
+      SIGNATURE *sig3 = crypto_sign_decode(jcr, mysignature2, size);
+      crypto_error_t c_err = crypto_sign_verify(sig3, pki_keypair_pub, signing_digest);
+      ok(signing_digest!=NULL && upd!=0 && ret && enc && sig2 != NULL && c_err== CRYPTO_ERROR_NONE, "second digest");
+      // the line below throw a Qmsg()
+      // openssl.c:79 OpenSSL digest Verify final failed: ERR=error:04091068:lib(4):func(145):reason(104)
+      crypto_error_t c_err2 = crypto_sign_verify(sig2, pki_keypair_pub, signing_digest);
+      ok(c_err2 == CRYPTO_ERROR_BAD_SIGNATURE, "second digest should not match first signature");
+      crypto_sign_free(sig);
+      crypto_sign_free(sig3);
+      crypto_digest_free(signing_digest);
+   }
+
+   // Release everything
+   crypto_sign_free(sig);
+   sig = NULL;
+   crypto_sign_free(sig2);
+   sig2 = NULL;
+
+   crypto_digest_free(signing_digest);
+   crypto_keypair_free(pki_keypair_pub);
+   crypto_keypair_free(pki_keypair_priv);
+   return 0;
+}
+
+int main()
+{
+   setup_daemon_message_queue(); // a Qmsg() is thrown
+   Unittests sign_test("crypto_test");
+   test_signature();
+   int ret = report();
+   free_daemon_message_queue();  // release the Qmsg()
+   return ret;
+}
+
+
index 2b4c8460205d36fdbfb47199b4af19da29f1ab3b..cdc9bf0e3cfb80578976b474ad8c8dfe8e603387 100644 (file)
@@ -22,6 +22,7 @@ ADD_TEST(unittests:scan-unittests "@regressdir@/tests/scan-unittests")
 ADD_TEST(unittests:base32-unittests "@regressdir@/tests/base32-unittests")
 ADD_TEST(unittests:base64-unittests "@regressdir@/tests/base64-unittests")
 ADD_TEST(unittests:bpipe-unittests "@regressdir@/tests/bpipe-unittests")
+ADD_TEST(unittests:crypto-unittests "@regressdir@/tests/bpipe-unittests")
 ADD_TEST(unittests:breaddir-unittests "@regressdir@/tests/breaddir-unittests")
 # Code not yet compatible with bsprintf
 # ADD_TEST(unittests:bsnprintf-unittests "@regressdir@/tests/bsnprintf-unittests")
diff --git a/regress/tests/crypto-unittests b/regress/tests/crypto-unittests
new file mode 100755 (executable)
index 0000000..d4bc392
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/sh
+#
+# Copyright (C) 2000-2018 Kern Sibbald
+# License: BSD 2-Clause; see file LICENSE-FOSS
+#
+# This is a lib/crypto.c unit test
+#
+TestName="crypto_test"
+. scripts/functions
+cp scripts/cryptokeypair.pem $tmp
+
+make -C $src/src/tools install-unittests
+
+if [ $? = 0 ] ; then
+   $bin/$TestName
+fi
+
+exit $?