Add regress coverage for bn_printf
authortb <tb@openbsd.org>
Thu, 6 Jul 2023 15:08:54 +0000 (15:08 +0000)
committertb <tb@openbsd.org>
Thu, 6 Jul 2023 15:08:54 +0000 (15:08 +0000)
This must be one of the ugliest tests I've ever written, but I can't think
of a better way of doing it.

regress/lib/libcrypto/bn/Makefile
regress/lib/libcrypto/bn/bn_print.c [new file with mode: 0644]

index 1b4d68b..1072f58 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.33 2023/06/03 21:20:29 tb Exp $
+#      $OpenBSD: Makefile,v 1.34 2023/07/06 15:08:54 tb Exp $
 
 PROGS +=       bn_add_sub
 PROGS +=       bn_cmp
@@ -12,6 +12,7 @@ PROGS +=      bn_mod_sqrt
 PROGS +=       bn_mont
 PROGS +=       bn_mul_div
 PROGS +=       bn_primes
+PROGS +=       bn_print
 PROGS +=       bn_rand_interval
 PROGS +=       bn_shift
 PROGS +=       bn_test
@@ -22,6 +23,7 @@ PROGS +=      bn_word
 STATIC_LINK += bn_gcd
 STATIC_LINK += bn_isqrt
 STATIC_LINK += bn_mod_exp
+STATIC_LINK += bn_print
 STATIC_LINK += bn_rand_interval
 STATIC_LINK += bn_test
 
diff --git a/regress/lib/libcrypto/bn/bn_print.c b/regress/lib/libcrypto/bn/bn_print.c
new file mode 100644 (file)
index 0000000..a19fa84
--- /dev/null
@@ -0,0 +1,280 @@
+/*     $OpenBSD: bn_print.c,v 1.1 2023/07/06 15:08:54 tb Exp $ */
+
+/*
+ * Copyright (c) 2023 Theo Buehler <tb@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <err.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/asn1.h>
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+
+#include "bn_local.h"
+
+#define BATIHDIDIDI "mana mana"
+#define BUF_MEM_LEN 1024
+
+static const char *pk = "040d305e1b159d03d0a17935b73a3c927aca151ccd62f39c"
+                       "265c073de554faa3d6cc12eaf4145fe88e19ab2f2e48e6ac"
+                       "184378acd037c3bdb2cd2ce647e21ae663b83d2e2f78c44f"
+                       "dbf40fa4684c55726b951d4e18429578cc373c91e29b652b"
+                       "29";
+
+const struct print_test {
+       const char *desc;
+       const char *want;
+} bn_print_tests[] = {
+       {
+               .desc = "zero",
+               .want = "    mana mana 0\n",
+       },
+       {
+               .desc = "minus one",
+               .want = "    mana mana 1 (0x1)\n",
+       },
+       {
+               .desc = "minus one",
+               .want = "    mana mana -1 (-0x1)\n",
+       },
+#ifdef _LP64
+       {
+               .desc = "largest word",
+               .want = "    mana mana 18446744073709551615 "
+                       "(0xffffffffffffffff)\n",
+       },
+       {
+               .desc = "smallest word",
+               .want = "    mana mana -18446744073709551615 "
+                       "(-0xffffffffffffffff)\n",
+       },
+       {
+               .desc = "largest negative non-word",
+               .want = "    mana mana (Negative)\n"
+                       "        01:00:00:00:00:00:00:00:00\n",
+       },
+       {
+               .desc = "smallest positive non-word",
+               .want = "    mana mana\n"
+                       "        01:00:00:00:00:00:00:00:00\n",
+       },
+#else
+       {
+               .desc = "largest word",
+               .want = "    mana mana 4294967295 (0xffffffff)\n",
+       },
+       {
+               .desc = "smallest word",
+               .want = "    mana mana -4294967295 (-0xffffffff)\n",
+       },
+       {
+               .desc = "largest negative non-word",
+               .want = "    mana mana (Negative)\n"
+                       "        01:00:00:00:00\n",
+       },
+       {
+               .desc = "smallest positive non-word",
+               .want = "    mana mana\n"
+                       "        01:00:00:00:00\n",
+       },
+#endif
+       {
+               .desc = "some pubkey",
+               .want = "    mana mana\n"
+                       "        04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n"
+                       "        92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n"
+                       "        fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n"
+                       "        48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n"
+                       "        47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n"
+                       "        a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37:\n"
+                       "        3c:91:e2:9b:65:2b:29\n",
+       },
+       {
+               .desc = "negated pubkey",
+               .want = "    mana mana (Negative)\n"
+                       "        04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n"
+                       "        92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n"
+                       "        fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n"
+                       "        48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n"
+                       "        47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n"
+                       "        a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37:\n"
+                       "        3c:91:e2:9b:65:2b:29\n",
+       },
+       {
+               .desc = "shifted negated pubkey",
+               .want = "    mana mana (Negative)\n"
+                       "        04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n"
+                       "        92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n"
+                       "        fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n"
+                       "        48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n"
+                       "        47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n"
+                       "        a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37\n",
+       },
+       {
+               .desc = "shifted pubkey",
+               .want = "    mana mana\n"
+                       "        04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n"
+                       "        92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n"
+                       "        fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n"
+                       "        48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n"
+                       "        47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n"
+                       "        a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37\n",
+       },
+};
+
+#define N_TESTCASES    (sizeof(bn_print_tests) / sizeof(bn_print_tests[0]))
+
+static int
+bn_print_testcase(const BIGNUM *bn, const struct print_test *test)
+{
+       BIO *bio;
+       char *got;
+       size_t want_len;
+       long got_len;
+       int failed = 1;
+
+       if ((bio = BIO_new(BIO_s_mem())) == NULL)
+               errx(1, "BIO_new");
+
+       if (!bn_printf(bio, bn, 4, "%s", BATIHDIDIDI))
+               errx(1, "bn_printf");
+
+       if ((got_len = BIO_get_mem_data(bio, &got)) < 0)
+               errx(1, "BIO_get_mem_data");
+
+       if ((want_len = strlen(test->want)) != (size_t)got_len) {
+               fprintf(stderr, "%s: want: %zu, got %ld\n",
+                   test->desc, want_len, got_len);
+               goto err;
+       }
+
+       if (strncmp(got, test->want, want_len) != 0) {
+               fprintf(stderr, "%s: strings differ\n", test->desc);
+               fprintf(stderr, "want: \"%s\"\ngot : \"%*s\"\n",
+                   test->want, (int)got_len, got);
+               goto err;
+       }
+
+       failed = 0;
+ err:
+       BIO_free(bio);
+
+       return failed;
+}
+
+int
+main(void)
+{
+       const struct print_test *test;
+       size_t testcase = 0;
+       BIO *bio;
+       BIGNUM *bn;
+       int failed = 0;
+
+       if ((bio = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL)
+               errx(1, "BIO_new_fp");
+
+       /* zero */
+       if ((bn = BN_new()) == NULL)
+               errx(1, "BN_new");
+       if (testcase >= N_TESTCASES)
+               errx(1, "Too many tests");
+       test = &bn_print_tests[testcase++];
+       failed |= bn_print_testcase(bn, test);
+
+       /* one */
+       if (!BN_set_word(bn, 1))
+               errx(1, "BIO_set_word");
+       if (testcase >= N_TESTCASES)
+               errx(1, "Too many tests");
+       test = &bn_print_tests[testcase++];
+       failed |= bn_print_testcase(bn, test);
+
+       /* minus one */
+       BN_set_negative(bn, 1);
+       if (testcase >= N_TESTCASES)
+               errx(1, "Too many tests");
+       test = &bn_print_tests[testcase++];
+       failed |= bn_print_testcase(bn, test);
+
+       /* largest word */
+       if (!BN_set_word(bn, ~0))
+               errx(1, "BN_set_word");
+       if (testcase >= N_TESTCASES)
+               errx(1, "Too many tests");
+       test = &bn_print_tests[testcase++];
+       failed |= bn_print_testcase(bn, test);
+
+       /* smallest word */
+       BN_set_negative(bn, 1);
+       if (testcase >= N_TESTCASES)
+               errx(1, "Too many tests");
+       test = &bn_print_tests[testcase++];
+       failed |= bn_print_testcase(bn, test);
+
+       /* largest negative non-word */
+       if (!BN_sub_word(bn, 1))
+               errx(1, "ASN1_bn_print");
+       if (testcase >= N_TESTCASES)
+               errx(1, "Too many tests");
+       test = &bn_print_tests[testcase++];
+       failed |= bn_print_testcase(bn, test);
+
+       /* smallest positive non-word */
+       BN_set_negative(bn, 0);
+       if (testcase >= N_TESTCASES)
+               errx(1, "Too many tests");
+       test = &bn_print_tests[testcase++];
+       failed |= bn_print_testcase(bn, test);
+
+       /* some pubkey */
+       if (BN_hex2bn(&bn, pk) == 0)
+               errx(1, "BN_hex2bn");
+       if (testcase >= N_TESTCASES)
+               errx(1, "Too many tests");
+       test = &bn_print_tests[testcase++];
+       failed |= bn_print_testcase(bn, test);
+
+       /* negated pubkey */
+       BN_set_negative(bn, 1);
+       if (testcase >= N_TESTCASES)
+               errx(1, "Too many tests");
+       test = &bn_print_tests[testcase++];
+       failed |= bn_print_testcase(bn, test);
+
+       /* shifted negated pubkey */
+       if (!BN_rshift(bn, bn, 7 * 8))
+               errx(1, "BN_rshift");
+       if (testcase >= N_TESTCASES)
+               errx(1, "Too many tests");
+       test = &bn_print_tests[testcase++];
+       failed |= bn_print_testcase(bn, test);
+
+       /* shifted pubkey */
+       BN_set_negative(bn, 0);
+       if (testcase >= N_TESTCASES)
+               errx(1, "Too many tests");
+       test = &bn_print_tests[testcase++];
+       failed |= bn_print_testcase(bn, test);
+
+       if (testcase != N_TESTCASES) {
+               warnx("Not all tests run");
+               failed |= 1;
+       }
+
+       return failed;
+}