From: Alain Spineux Date: Mon, 19 Sep 2022 12:19:11 +0000 (+0200) Subject: regress: add a crypto-unittest X-Git-Tag: Beta-15.0.0~441 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=802a804b619c08367a83a2487f67f42f89896397;p=thirdparty%2Fbacula.git regress: add a crypto-unittest - the main goal is to learn how the use the crypt_* function - for now test only signature part --- diff --git a/bacula/src/tools/Makefile.in b/bacula/src/tools/Makefile.in index 3e17f4d0b..71e5f135b 100644 --- a/bacula/src/tools/Makefile.in +++ b/bacula/src/tools/Makefile.in @@ -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 index 000000000..83d0eee57 --- /dev/null +++ b/bacula/src/tools/crypto_test.c @@ -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; +} + + diff --git a/regress/DartTestfile.txt.in b/regress/DartTestfile.txt.in index 2b4c84602..cdc9bf0e3 100644 --- a/regress/DartTestfile.txt.in +++ b/regress/DartTestfile.txt.in @@ -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 index 000000000..d4bc3927e --- /dev/null +++ b/regress/tests/crypto-unittests @@ -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 $?