From e49e90f0fa342552eab5cf6335cde9728aa6e502 Mon Sep 17 00:00:00 2001 From: GimmeHardware <23285878+jcastle-gh@users.noreply.github.com> Date: Fri, 14 Mar 2025 20:59:27 -0400 Subject: [PATCH] ed25519 tests, perf test fix, dkim_free() memory leak, dkim_sig_keybits() Add 4 ed25519 directed tests and 2 ed25519 performance test scripts. In the Makefile t-cleanup is not part of $check_PROGRAMS anymore so that it can can be run after the $check_SCRIPTS tests instead of before them, allowing those tests to use the keyfile that t-cleanup deletes. Also fix 3 bugs found while doing the above. 1. The t-signperf and t-verifyperf performance tests were blindly looping on sign and verify operations without checking for correct results. They always reported "pass" even when the operation failed, for example when the key was not found. Now they assert the results and "fail" if something goes wrong. 2. In dkim_free() the ed25519 crypto structure wasn't getting freed. 3. In dkim_sig_keybits() the wrong size was being returned for ed25519. For now, always return 256 since ed25519 is always 256-bit. The underlying bug is in the calculation of 'keybits' in various other dkim functions and that will be fixed in a subesquent PR. --- libopendkim/dkim.c | 15 +- libopendkim/tests/Makefile.am | 17 +- libopendkim/tests/t-setup.c | 8 + libopendkim/tests/t-signperf-ed25519 | 6 + libopendkim/tests/t-signperf.c | 51 +++- libopendkim/tests/t-test200.c | 215 +++++++++++++++++ libopendkim/tests/t-test201.c | 318 ++++++++++++++++++++++++ libopendkim/tests/t-test202.c | 321 +++++++++++++++++++++++++ libopendkim/tests/t-test203.c | 230 ++++++++++++++++++ libopendkim/tests/t-testdata.h | 29 +++ libopendkim/tests/t-verifyperf-ed25519 | 6 + libopendkim/tests/t-verifyperf.c | 60 ++++- 12 files changed, 1245 insertions(+), 31 deletions(-) create mode 100755 libopendkim/tests/t-signperf-ed25519 create mode 100644 libopendkim/tests/t-test200.c create mode 100644 libopendkim/tests/t-test201.c create mode 100644 libopendkim/tests/t-test202.c create mode 100644 libopendkim/tests/t-test203.c create mode 100755 libopendkim/tests/t-verifyperf-ed25519 diff --git a/libopendkim/dkim.c b/libopendkim/dkim.c index e429a6fc..cfb8227d 100644 --- a/libopendkim/dkim.c +++ b/libopendkim/dkim.c @@ -5131,7 +5131,8 @@ dkim_free(DKIM *dkim) CLOBBER(dkim->dkim_siglist[c]->sig_key); CLOBBER(dkim->dkim_siglist[c]->sig_sig); - if (dkim->dkim_siglist[c]->sig_keytype == DKIM_KEYTYPE_RSA) + if (dkim->dkim_siglist[c]->sig_keytype == DKIM_KEYTYPE_RSA || + dkim->dkim_siglist[c]->sig_keytype == DKIM_KEYTYPE_ED25519) { struct dkim_crypto *crypto; @@ -7910,11 +7911,17 @@ dkim_sig_getkeysize(DKIM_SIGINFO *sig, unsigned int *bits) assert(sig != NULL); assert(bits != NULL); - if (sig->sig_keybits == 0 && - sig->sig_signalg != DKIM_SIGN_ED25519SHA256) + if (sig->sig_keybits == 0) return DKIM_STAT_INVALID; - *bits = sig->sig_keybits; + if(sig->sig_signalg == DKIM_SIGN_ED25519SHA256) + { + *bits = 256; + } + else + { + *bits = sig->sig_keybits; + } return DKIM_STAT_OK; } diff --git a/libopendkim/tests/Makefile.am b/libopendkim/tests/Makefile.am index 293a9227..45854eaf 100644 --- a/libopendkim/tests/Makefile.am +++ b/libopendkim/tests/Makefile.am @@ -42,14 +42,21 @@ check_PROGRAMS = t-setup t-test00 t-test01 t-test02 t-test03 t-test04 \ t-test145 t-test146 t-test147 t-test148 t-test149 t-test150 \ t-test151 t-test152 t-test153 t-test154 t-test155 t-test156 \ t-test157 t-test158 t-test159 \ + t-test200 t-test201 t-test202 t-test203 \ t-signperf t-verifyperf check_SCRIPTS = t-signperf-sha1 t-signperf-relaxed-relaxed \ - t-signperf-simple-simple + t-signperf-simple-simple \ + t-signperf-ed25519 t-verifyperf-ed25519 if ALL_SYMBOLS check_PROGRAMS += t-test49 t-test113 t-test118 endif -check_PROGRAMS += t-cleanup -TESTS = $(check_PROGRAMS) $(check_SCRIPTS) + +# t-cleanup can't be in check_PROGRAMS. It has to run last, after scripts. +# Put it in EXTRA_PROGRAMS so automake will still build it on demand. +EXTRA_PROGRAMS = t-cleanup +CLEANFILES = t-cleanup + +TESTS = $(check_PROGRAMS) $(check_SCRIPTS) t-cleanup EXTRA_DIST = $(check_SCRIPTS) @@ -219,6 +226,10 @@ t_test156_SOURCES = t-test156.c t-testdata.h t_test157_SOURCES = t-test157.c t-testdata.h t_test158_SOURCES = t-test158.c t-testdata.h t_test159_SOURCES = t-test159.c t-testdata.h +t_test200_SOURCES = t-test200.c t-testdata.h +t_test201_SOURCES = t-test201.c t-testdata.h +t_test202_SOURCES = t-test202.c t-testdata.h +t_test203_SOURCES = t-test203.c t-testdata.h MOSTLYCLEANFILES= diff --git a/libopendkim/tests/t-setup.c b/libopendkim/tests/t-setup.c index 2b0169d7..d93e67e9 100644 --- a/libopendkim/tests/t-setup.c +++ b/libopendkim/tests/t-setup.c @@ -130,6 +130,14 @@ main(int argc, char **argv) } fprintf(f, "\n"); + fprintf(f, "%s.%s.%s ", SELECTORRFC8463, DKIM_DNSKEYNAME, DOMAIN); + for (p = RFC8463_ED25519PUBLICKEY; *p != '\0'; p++) + { + if (*p != '\n') + putc(*p, f); + } + fprintf(f, "\n"); + fprintf(f, "dkim=all; t=s; r=%s\n", REPLYADDRESS); fprintf(f, "%s exists\n", DOMAIN2); diff --git a/libopendkim/tests/t-signperf-ed25519 b/libopendkim/tests/t-signperf-ed25519 new file mode 100755 index 00000000..7c59fd89 --- /dev/null +++ b/libopendkim/tests/t-signperf-ed25519 @@ -0,0 +1,6 @@ +#!/bin/sh +# +# +# Speed signing test using ed25519 algorithm + +./t-signperf -s ed25519-sha256 diff --git a/libopendkim/tests/t-signperf.c b/libopendkim/tests/t-signperf.c index a6939bae..fa3f7e1a 100644 --- a/libopendkim/tests/t-signperf.c +++ b/libopendkim/tests/t-signperf.c @@ -10,6 +10,7 @@ /* system includes */ #include +#include #include #include #include @@ -105,6 +106,8 @@ alg_code(char *name) return (dkim_alg_t) DKIM_SIGN_RSASHA1; else if (strcasecmp(name, "rsa-sha256") == 0) return (dkim_alg_t) DKIM_SIGN_RSASHA256; + else if (strcasecmp(name, "ed25519-sha256") == 0) + return (dkim_alg_t) DKIM_SIGN_ED25519SHA256; else return (dkim_alg_t) DKIM_SIGN_UNKNOWN; } @@ -133,6 +136,9 @@ alg_name(dkim_alg_t code) case DKIM_SIGN_RSASHA256: return "rsa-sha256"; + case DKIM_SIGN_ED25519SHA256: + return "ed25519-sha256"; + case DKIM_SIGN_UNKNOWN: default: return "unknown"; @@ -188,6 +194,9 @@ main(int argc, char **argv) DKIM *dkim; DKIM_LIB *lib; dkim_sigkey_t key; + int keybits; + const char *selector; + unsigned int seed; unsigned char hdr[MAXHEADER + 1]; unsigned char body[BODYBUFRSZ]; time_t start = DEFTESTINT; @@ -274,23 +283,38 @@ main(int argc, char **argv) else signalg = DKIM_SIGN_RSASHA1; } - else if (signalg == DKIM_SIGN_RSASHA256 && - !dkim_libfeature(lib, DKIM_FEATURE_SHA256)) + else if ((signalg == DKIM_SIGN_RSASHA256 && + !dkim_libfeature(lib, DKIM_FEATURE_SHA256)) || + (signalg == DKIM_SIGN_ED25519SHA256 && + (!dkim_libfeature(lib, DKIM_FEATURE_ED25519) || + !dkim_libfeature(lib, DKIM_FEATURE_SHA256)))) { fprintf(stdout, - "### requested signing algorithm not available\n"); + "### algorithm %s not available SKIPPED\n", alg_name(signalg)); dkim_close(lib); - return 1; + return 0; } - fprintf(stdout, - "*** SIGNING SPEED TEST: %s/%s with %s, size %u for %lds\n", - canon_name(hcanon), canon_name(bcanon), alg_name(signalg), - (unsigned int) msgsize, (long) testint); + if (signalg == DKIM_SIGN_ED25519SHA256) + { + key = RFC8463_ED25519KEY; + keybits = 256; + selector = SELECTORRFC8463; + } + else + { + key = KEY; + keybits = 1024; + selector = SELECTOR; + } - key = KEY; + seed = time(NULL); + srandom(seed); - srandom(time(NULL)); + fprintf(stdout, + "*** SIGNING SPEED TEST: %d-bit %s/%s with %s, body size %u for %lds, random seed %u\n", + keybits, canon_name(hcanon), canon_name(bcanon), alg_name(signalg), + (unsigned int) msgsize, (long) testint, seed); /* prepare a random body buffer */ for (c = 0, w = 0; c < sizeof body; c++) @@ -310,8 +334,9 @@ main(int argc, char **argv) while (time(NULL) < start + testint) { - dkim = dkim_sign(lib, JOBID, NULL, key, SELECTOR, DOMAIN, + dkim = dkim_sign(lib, JOBID, NULL, key, selector, DOMAIN, hcanon, bcanon, signalg, -1L, &status); + assert(status == DKIM_STAT_OK); status = dkim_header(dkim, HEADER02, strlen(HEADER02)); @@ -329,7 +354,7 @@ main(int argc, char **argv) status = dkim_header(dkim, HEADER09, strlen(HEADER09)); - status = dkim_eoh(dkim); + assert(dkim_eoh(dkim) == DKIM_STAT_OK); msgrem = msgsize; @@ -344,7 +369,7 @@ main(int argc, char **argv) (void) dkim_body(dkim, CRLF, 2); - status = dkim_eom(dkim, NULL); + assert(dkim_eom(dkim, NULL) == DKIM_STAT_OK); memset(hdr, '\0', sizeof hdr); status = dkim_getsighdr(dkim, hdr, sizeof hdr, diff --git a/libopendkim/tests/t-test200.c b/libopendkim/tests/t-test200.c new file mode 100644 index 00000000..c289c11b --- /dev/null +++ b/libopendkim/tests/t-test200.c @@ -0,0 +1,215 @@ +/* +** Copyright (c) 2005-2008 Sendmail, Inc. and its suppliers. +** All rights reserved. +** +** Copyright (c) 2009, 2011, 2012, The Trusted Domain Project. +** All rights reserved. +*/ + +#include "build-config.h" + +/* system includes */ +#include +#include +#include +#include + +#ifdef USE_GNUTLS +# include +#endif /* USE_GNUTLS */ + +/* libopendkim includes */ +#include "../dkim.h" +#include "t-testdata.h" + +#define MAXHEADER 4096 + +#define SIG1 "v=1; a=ed25519-sha256; c=relaxed/relaxed;\r\n" \ + " d=football.example.com; i=@football.example.com;\r\n" \ + " q=dns/txt; s=brisbane; t=1528637909; h=from : to :\r\n" \ + " subject : date : message-id : from : subject : date;\r\n" \ + " bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;\r\n" \ + " b=/gCrinpcQOoIfuHNQIbq4pgh9kyIK3AQUdt9OdqQehSwhEIug4D11Bus\r\n" \ + " Fa3bT3FY5OsU7ZbnKELq+eXdp1Q1Dw==\r\n" + +#define SIG2 "v=1; a=rsa-sha256; c=relaxed/relaxed;\r\n" \ + " d=football.example.com; i=@football.example.com;\r\n" \ + " q=dns/txt; s=test; t=1528637909; h=from : to : subject :\r\n" \ + " date : message-id : from : subject : date;\r\n" \ + " bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;\r\n" \ + " b=F45dVWDfMbQDGHJFlXUNB2HKfbCeLRyhDXgFpEL8GwpsRe0IeIixNTe3\r\n" \ + " DhCVlUrSjV4BwcVcOF6+FF3Zo9Rpo1tFOeS9mPYQTnGdaSGsgeefOsk2Jz\r\n" \ + " dA+L10TeYt9BgDfQNZtKdN1WO//KgIqXP7OdEFE4LjFYNcUxZQ4FADY+8=\r\n" + +const char rfc8463_ed25519_selector[] = "brisbane"; +const char rfc8463_rsa_selector[] = "test"; +const char rfc8463_domain[] = "football.example.com"; + +int kl; + + +DKIM_STAT +key_lookup(DKIM *dkim, DKIM_SIGINFO *sig, unsigned char *buf, size_t buflen) +{ + const char *selector; + const char *domain; + + assert(dkim != NULL); + assert(sig != NULL); + assert(buf != NULL); + + selector = dkim_sig_getselector(sig); + assert(selector != NULL); + assert(!strcmp(selector, rfc8463_ed25519_selector) || + !strcmp(selector, rfc8463_rsa_selector)); + + domain = dkim_sig_getdomain(sig); + assert(domain != NULL); + assert(strcmp(domain, rfc8463_domain) == 0); + + memset(buf, '\0', buflen); + if(!strcmp(selector, rfc8463_ed25519_selector)) + { + strncpy(buf, RFC8463_ED25519PUBLICKEY, buflen); + } + else + { + strncpy(buf, RFC8463_RSAPUBLICKEY, buflen); + } + + kl += 1; + + return DKIM_STAT_OK; +} + +/* +** MAIN -- program mainline +** +** Parameters: +** The usual. +** +** Return value: +** Exit status. +*/ + +int +main(int argc, char **argv) +{ +#ifdef TEST_KEEP_FILES + u_int flags; +#endif /* TEST_KEEP_FILES */ + DKIM_STAT status; + DKIM *dkim; + DKIM_LIB *lib; + DKIM_SIGINFO **sigs; + int nsigs; + dkim_alg_t alg[2]; + unsigned int bits[2]; + unsigned char hdr[MAXHEADER + 1]; + + kl = 0; + +#ifdef USE_GNUTLS + (void) gnutls_global_init(); +#endif /* USE_GNUTLS */ + + /* instantiate the library */ + lib = dkim_init(NULL, NULL); + assert(lib != NULL); + + if (!dkim_libfeature(lib, DKIM_FEATURE_ED25519) || + !dkim_libfeature(lib, DKIM_FEATURE_SHA256)) + { + printf("*** relaxed/relaxed ed25519-sha256/rsa-sha256 rfc8463 example verifying SKIPPED\n"); + dkim_close(lib); + return 0; + } + + printf("*** relaxed/relaxed ed25519-sha256/rsa-sha256 rfc8463 example verifying\n"); + +#ifdef TEST_KEEP_FILES + /* set flags */ + flags = (DKIM_LIBFLAGS_TMPFILES|DKIM_LIBFLAGS_KEEPFILES); + (void) dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_FLAGS, &flags, + sizeof flags); +#endif /* TEST_KEEP_FILES */ + + /* supply the right pubkey above */ + status = dkim_set_key_lookup(lib, key_lookup); + assert(status == DKIM_STAT_OK); + + dkim = dkim_verify(lib, JOBID, NULL, &status); + assert(dkim != NULL); + + snprintf(hdr, sizeof hdr, "%s: %s", DKIM_SIGNHEADER, SIG1); + status = dkim_header(dkim, hdr, strlen(hdr)); + assert(status == DKIM_STAT_OK); + + snprintf(hdr, sizeof hdr, "%s: %s", DKIM_SIGNHEADER, SIG2); + status = dkim_header(dkim, hdr, strlen(hdr)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, THEADER00, strlen(THEADER00)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, THEADER01, strlen(THEADER01)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, THEADER02, strlen(THEADER02)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, THEADER03, strlen(THEADER03)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, THEADER04, strlen(THEADER04)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, THEADER05, strlen(THEADER05)); + assert(status == DKIM_STAT_OK); + + status = dkim_eoh(dkim); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, TBODY, strlen(TBODY)); + assert(status == DKIM_STAT_OK); + + status = dkim_eom(dkim, NULL); + /* save dkim_eom status to be checked below, after sig results */ + + nsigs = 0; + assert(dkim_getsiglist(dkim, &sigs, &nsigs) == DKIM_STAT_OK); + assert(nsigs == 2); + + assert(dkim_sig_getsignalg(sigs[0], &alg[0]) == DKIM_STAT_OK); + assert(dkim_sig_getsignalg(sigs[1], &alg[1]) == DKIM_STAT_OK); + assert(alg[0] == DKIM_SIGN_RSASHA256 || alg[1] == DKIM_SIGN_RSASHA256); + assert(alg[0] == DKIM_SIGN_ED25519SHA256 || alg[1] == DKIM_SIGN_ED25519SHA256); + + assert(dkim_sig_getkeysize(sigs[0], &bits[0]) == DKIM_STAT_OK); + assert(dkim_sig_getkeysize(sigs[1], &bits[1]) == DKIM_STAT_OK); + if(alg[0] == DKIM_SIGN_RSASHA256) + { + assert(bits[0] == 1024); + assert(bits[1] == 256); + } + else + { + assert(bits[0] == 256); + assert(bits[1] == 1024); + } + + assert(dkim_sig_geterror(sigs[0]) == DKIM_SIGERROR_OK); + assert(dkim_sig_geterror(sigs[1]) == DKIM_SIGERROR_OK); + + /* Now assert dkim_eom() success */ + assert(status == DKIM_STAT_OK); + + status = dkim_free(dkim); + assert(status == DKIM_STAT_OK); + + assert(kl == 2); + + dkim_close(lib); + + return 0; +} diff --git a/libopendkim/tests/t-test201.c b/libopendkim/tests/t-test201.c new file mode 100644 index 00000000..b52c5f3e --- /dev/null +++ b/libopendkim/tests/t-test201.c @@ -0,0 +1,318 @@ +/* +** Copyright (c) 2005-2008 Sendmail, Inc. and its suppliers. +** All rights reserved. +** +** Copyright (c) 2009, 2011-2013, The Trusted Domain Project. +** All rights reserved. +*/ + +#include "build-config.h" + +/* system includes */ +#include +#include +#include +#include +#include + +#ifdef USE_GNUTLS +# include +#endif /* USE_GNUTLS */ + +/* libopendkim includes */ +#include "../dkim.h" +#include "t-testdata.h" + +#define MAXHEADER 4096 + +#define SIG2 "v=1; a=ed25519-sha256; c=relaxed/simple; d=example.com;\r\n\ts=rfc8463; t=1172620939;\r\n\tbh=yHBAX+3IwxTZIynBuB/5tlsBInJq9n8qz5fgAycHi80=;\r\n\th=Received:Received:Received:From:To:Date:Subject:Message-ID;\r\n\tb=lJLMsoVI4qnYwS4OImCdrD532WVKC+ZhSh1nWKp87QOrc4PXeozUWaumYHTVhoyOP\r\n\t h7OEDn+g4WAypNDHxaCDA==" + +struct malloc_track +{ + size_t mt_size; + void * mt_ptr; + struct malloc_track * mt_next; +}; + +unsigned int mtsize; +unsigned int mtcount; +struct malloc_track *mtstack; + +/* +** DEBUG_INIT -- initialize tracking malloc() wrapper +** +** Parameters: +** None. +** +** Return value: +** None. +*/ + +void +debug_init(void) +{ + mtstack = NULL; + mtsize = 0; + mtcount = 0; +} + +/* +** DEBUG_MALLOC -- tracking malloc() wrapper +** +** Parameters: +** closure -- memory closure (not used) +** nbytes -- how many bytes to get +** +** Return value: +** Pointer to allocated memory. +*/ + +void * +debug_malloc(void *closure, size_t nbytes) +{ + struct malloc_track *new; + void *ptr; + + assert(nbytes > 0); + + new = (void *) malloc(sizeof(struct malloc_track)); + if (new == NULL) + return NULL; + + ptr = (void *) malloc(nbytes); + if (new == NULL) + return NULL; + + new->mt_next = mtstack; + new->mt_ptr = ptr; + new->mt_size = nbytes; + mtstack = new; + mtsize++; + mtcount++; + + return ptr; +} + +/* +** DEBUG_FREE -- tracking wrapper for free() +** +** Parameters: +** closure -- memory closure (not used) +** ptr -- pointer to free +** +** Return value: +** None. +*/ + +void +debug_free(void *closure, void *ptr) +{ + struct malloc_track *mt; + struct malloc_track *last; + + assert(ptr != NULL); + assert(mtstack != NULL); + + mt = mtstack; + last = NULL; + while (mt != NULL) + { + if (mt->mt_ptr == ptr) + { + if (mt == mtstack) + mtstack = mt->mt_next; + else + last->mt_next = mt->mt_next; + + free(mt); + free(ptr); + mtsize--; + return; + } + + last = mt; + mt = mt->mt_next; + } + + assert(0); +} + +/* +** DEBUG_DUMP -- return contents of malloc tracking +** +** Parameters: +** out -- stream to which to write +** +** Return value: +** None. +*/ + +void +debug_dump(FILE *out) +{ + struct malloc_track *mt; + + assert(out != NULL); + + fprintf(out, "--- %u allocation(s) recorded\n", mtcount); + + if (mtstack != NULL) + { + fprintf(out, "--- %u dangling allocation(s):\n", mtsize); + + mt = mtstack; + while (mt != NULL) + { + fprintf(out, "\t%p %lu\n", mt->mt_ptr, + (unsigned long) mt->mt_size); + mt = mt->mt_next; + } + } +} + +/* +** MAIN -- program mainline +** +** Parameters: +** The usual. +** +** Return value: +** Exit status. +*/ + +int +main(int argc, char **argv) +{ +#ifdef TEST_KEEP_FILES + u_int flags; +#endif /* TEST_KEEP_FILES */ + DKIM_STAT status; + DKIM *dkim; + DKIM_LIB *lib; + dkim_query_t qtype = DKIM_QUERY_FILE; + unsigned char hdr[MAXHEADER + 1]; + + debug_init(); + +#ifdef USE_GNUTLS + (void) gnutls_global_init(); +#endif /* USE_GNUTLS */ + + /* instantiate the library */ + lib = dkim_init(debug_malloc, debug_free); + assert(lib != NULL); + + if (!dkim_libfeature(lib, DKIM_FEATURE_ED25519) || + !dkim_libfeature(lib, DKIM_FEATURE_SHA256)) + { + printf("*** relaxed/simple ed25519-sha256 verifying with leak detection SKIPPED\n"); + dkim_close(lib); + return 0; + } + + printf("*** relaxed/simple ed25519-sha256 verifying with leak detection\n"); + +#ifdef TEST_KEEP_FILES + /* set flags */ + flags = (DKIM_LIBFLAGS_TMPFILES|DKIM_LIBFLAGS_KEEPFILES); + (void) dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_FLAGS, &flags, + sizeof flags); +#endif /* TEST_KEEP_FILES */ + + (void) dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_QUERYMETHOD, + &qtype, sizeof qtype); + (void) dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_QUERYINFO, + KEYFILE, strlen(KEYFILE)); + + dkim = dkim_verify(lib, JOBID, NULL, &status); + assert(dkim != NULL); + + snprintf(hdr, sizeof hdr, "%s: %s", DKIM_SIGNHEADER, SIG2); + status = dkim_header(dkim, hdr, strlen(hdr)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER01, strlen(HEADER01)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER02, strlen(HEADER02)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER03, strlen(HEADER03)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER04, strlen(HEADER04)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER05, strlen(HEADER05)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER06, strlen(HEADER06)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER07, strlen(HEADER07)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER08, strlen(HEADER08)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER09, strlen(HEADER09)); + assert(status == DKIM_STAT_OK); + + status = dkim_eoh(dkim); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY00, strlen(BODY00)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY01, strlen(BODY01)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY01A, strlen(BODY01A)); + assert(status == DKIM_STAT_OK); + status = dkim_body(dkim, BODY01B, strlen(BODY01B)); + assert(status == DKIM_STAT_OK); + status = dkim_body(dkim, BODY01C, strlen(BODY01C)); + assert(status == DKIM_STAT_OK); + status = dkim_body(dkim, BODY01D, strlen(BODY01D)); + assert(status == DKIM_STAT_OK); + status = dkim_body(dkim, BODY01E, strlen(BODY01E)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY02, strlen(BODY02)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY03, strlen(BODY03)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY04, strlen(BODY04)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY03, strlen(BODY03)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY03, strlen(BODY03)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY05, strlen(BODY05)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY03, strlen(BODY03)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY03, strlen(BODY03)); + assert(status == DKIM_STAT_OK); + + status = dkim_eom(dkim, NULL); + assert(status == DKIM_STAT_OK); + + status = dkim_free(dkim); + assert(status == DKIM_STAT_OK); + + debug_dump(stdout); + assert(mtsize == 0); + assert(mtstack == NULL); + + dkim_close(lib); + + return 0; +} diff --git a/libopendkim/tests/t-test202.c b/libopendkim/tests/t-test202.c new file mode 100644 index 00000000..34791a57 --- /dev/null +++ b/libopendkim/tests/t-test202.c @@ -0,0 +1,321 @@ +/* +** Copyright (c) 2005-2008 Sendmail, Inc. and its suppliers. +** All rights reserved. +** +** Copyright (c) 2009, 2011-2013, The Trusted Domain Project. +** All rights reserved. +*/ + +#include "build-config.h" + +/* system includes */ +#include +#include +#include +#include +#include + +#ifdef USE_GNUTLS +# include +#endif /* USE_GNUTLS */ + +/* libopendkim includes */ +#include "../dkim.h" +#include "t-testdata.h" + +#define MAXHEADER 4096 + +#define SIG2 "v=1; a=ed25519-sha256; c=relaxed/simple; d=example.com;\r\n\ts=rfc8463; t=1172620939;\r\n\tbh=yHBAX+3IwxTZIynBuB/5tlsBInJq9n8qz5fgAycHi80=;\r\n\th=Received:Received:Received:From:To:Date:Subject:Message-ID;\r\n\tb=lJLMsoVI4qnYwS4OImCdrD532WVKC+ZhSh1nWKp87QOrc4PXeozUWaumYHTVhoyOP\r\n\t h7OEDn+g4WAypNDHxaCDA==" + +struct malloc_track +{ + size_t mt_size; + void * mt_ptr; + struct malloc_track * mt_next; +}; + +unsigned int mtsize; +unsigned int mtcount; +struct malloc_track *mtstack; + +/* +** DEBUG_INIT -- initialize tracking malloc() wrapper +** +** Parameters: +** None. +** +** Return value: +** None. +*/ + +void +debug_init(void) +{ + mtstack = NULL; + mtsize = 0; + mtcount = 0; +} + +/* +** DEBUG_MALLOC -- tracking malloc() wrapper +** +** Parameters: +** closure -- memory closure (not used) +** nbytes -- how many bytes to get +** +** Return value: +** Pointer to allocated memory. +*/ + +void * +debug_malloc(void *closure, size_t nbytes) +{ + struct malloc_track *new; + void *ptr; + + assert(nbytes > 0); + + new = (void *) malloc(sizeof(struct malloc_track)); + if (new == NULL) + return NULL; + + ptr = (void *) malloc(nbytes); + if (new == NULL) + return NULL; + + new->mt_next = mtstack; + new->mt_ptr = ptr; + new->mt_size = nbytes; + mtstack = new; + mtsize++; + mtcount++; + + return ptr; +} + +/* +** DEBUG_FREE -- tracking wrapper for free() +** +** Parameters: +** closure -- memory closure (not used) +** ptr -- pointer to free +** +** Return value: +** None. +*/ + +void +debug_free(void *closure, void *ptr) +{ + struct malloc_track *mt; + struct malloc_track *last; + + assert(ptr != NULL); + assert(mtstack != NULL); + + mt = mtstack; + last = NULL; + while (mt != NULL) + { + if (mt->mt_ptr == ptr) + { + if (mt == mtstack) + mtstack = mt->mt_next; + else + last->mt_next = mt->mt_next; + + free(mt); + free(ptr); + mtsize--; + return; + } + + last = mt; + mt = mt->mt_next; + } + + assert(0); +} + +/* +** DEBUG_DUMP -- return contents of malloc tracking +** +** Parameters: +** out -- stream to which to write +** +** Return value: +** None. +*/ + +void +debug_dump(FILE *out) +{ + struct malloc_track *mt; + + assert(out != NULL); + + fprintf(out, "--- %u allocation(s) recorded\n", mtcount); + + if (mtstack != NULL) + { + fprintf(out, "--- %u dangling allocation(s):\n", mtsize); + + mt = mtstack; + while (mt != NULL) + { + fprintf(out, "\t%p %lu\n", mt->mt_ptr, + (unsigned long) mt->mt_size); + mt = mt->mt_next; + } + } +} +/* +** MAIN -- program mainline +** +** Parameters: +** The usual. +** +** Return value: +** Exit status. +*/ + +int +main(int argc, char **argv) +{ +#ifdef TEST_KEEP_FILES + u_int flags; +#endif /* TEST_KEEP_FILES */ + DKIM_STAT status; + uint64_t fixed_time; + DKIM *dkim; + DKIM_LIB *lib; + dkim_sigkey_t key; + unsigned char hdr[MAXHEADER + 1]; + + debug_init(); + +#ifdef USE_GNUTLS + (void) gnutls_global_init(); +#endif /* USE_GNUTLS */ + + /* instantiate the library */ + lib = dkim_init(debug_malloc, debug_free); + assert(lib != NULL); + + if (!dkim_libfeature(lib, DKIM_FEATURE_ED25519) || + !dkim_libfeature(lib, DKIM_FEATURE_SHA256)) + { + printf("*** relaxed/simple ed25519-sha256 signing with leak detection SKIPPED\n"); + dkim_close(lib); + return 0; + } + + printf("*** relaxed/simple ed25519-sha256 signing with leak detection\n"); + +#ifdef TEST_KEEP_FILES + /* set flags */ + flags = (DKIM_LIBFLAGS_TMPFILES|DKIM_LIBFLAGS_KEEPFILES); + (void) dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_FLAGS, &flags, + sizeof flags); +#endif /* TEST_KEEP_FILES */ + + key = RFC8463_ED25519KEY; + + dkim = dkim_sign(lib, JOBID, NULL, key, SELECTORRFC8463, DOMAIN, + DKIM_CANON_RELAXED, DKIM_CANON_SIMPLE, + DKIM_SIGN_ED25519SHA256, -1L, &status); + assert(dkim != NULL); + + /* fix signing time */ + fixed_time = 1172620939; + (void) dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_FIXEDTIME, + &fixed_time, sizeof fixed_time); + + status = dkim_header(dkim, HEADER02, strlen(HEADER02)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER03, strlen(HEADER03)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER04, strlen(HEADER04)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER05, strlen(HEADER05)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER06, strlen(HEADER06)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER07, strlen(HEADER07)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER08, strlen(HEADER08)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER09, strlen(HEADER09)); + assert(status == DKIM_STAT_OK); + + status = dkim_eoh(dkim); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY00, strlen(BODY00)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY01, strlen(BODY01)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY01A, strlen(BODY01A)); + assert(status == DKIM_STAT_OK); + status = dkim_body(dkim, BODY01B, strlen(BODY01B)); + assert(status == DKIM_STAT_OK); + status = dkim_body(dkim, BODY01C, strlen(BODY01C)); + assert(status == DKIM_STAT_OK); + status = dkim_body(dkim, BODY01D, strlen(BODY01D)); + assert(status == DKIM_STAT_OK); + status = dkim_body(dkim, BODY01E, strlen(BODY01E)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY02, strlen(BODY02)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY03, strlen(BODY03)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY04, strlen(BODY04)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY03, strlen(BODY03)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY03, strlen(BODY03)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY05, strlen(BODY05)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY03, strlen(BODY03)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY03, strlen(BODY03)); + assert(status == DKIM_STAT_OK); + + status = dkim_eom(dkim, NULL); + assert(status == DKIM_STAT_OK); + + memset(hdr, '\0', sizeof hdr); + status = dkim_getsighdr(dkim, hdr, sizeof hdr, + strlen(DKIM_SIGNHEADER) + 2); + assert(status == DKIM_STAT_OK); + assert(strcmp(SIG2, hdr) == 0); + + status = dkim_free(dkim); + assert(status == DKIM_STAT_OK); + + debug_dump(stdout); + assert(mtsize == 0); + assert(mtstack == NULL); + + dkim_close(lib); + + return 0; +} diff --git a/libopendkim/tests/t-test203.c b/libopendkim/tests/t-test203.c new file mode 100644 index 00000000..7485156f --- /dev/null +++ b/libopendkim/tests/t-test203.c @@ -0,0 +1,230 @@ +/* +** Copyright (c) 2005-2008 Sendmail, Inc. and its suppliers. +** All rights reserved. +** +** Copyright (c) 2009, 2011, 2012, The Trusted Domain Project. +** All rights reserved. +*/ + +#include "build-config.h" + +/* system includes */ +#include +#include +#include +#include +#include + +#ifdef USE_GNUTLS +# include +#endif /* USE_GNUTLS */ + +/* libopendkim includes */ +#include "../dkim.h" +#include "t-testdata.h" + +#define MAXHEADER 4096 + +#define SIG1 "v=1; a=rsa-sha1; c=relaxed/simple; d=example.com; s=test;\r\n\tt=1172620939; bh=ll/0h2aWgG+D3ewmE4Y3pY7Ukz8=; h=Received:Received:\r\n\t Received:From:To:Date:Subject:Message-ID; b=bj9kVUbnBYfe9sVzH9lT45\r\n\tTFKO3eQnDbXLfgmgu/b5QgxcnhT9ojnV2IAM4KUO8+hOo5sDEu5Co/0GASH0vHpSV4P\r\n\t377Iwew3FxvLpHsVbVKgXzoKD4QSbHRpWNxyL6LypaaqFa96YqjXuYXr0vpb88hticn\r\n\t6I16//WThMz8fMU=" +#define SIG2 "v=1; a=ed25519-sha256; c=relaxed/relaxed; d=example.com;\r\n\ts=rfc8463; t=1172620939;\r\n\tbh=QVUr2KBvm7/Q/ustiYzOlFMN9G8IMqBzUX81BdpjSDI=;\r\n\th=Received:Received:Received:From:To:Date:Subject:Message-ID;\r\n\tb=PJWxH/BmbjT09GmNSVFBEcMJFpyga2kptY8s2YqB+PZ3Ctzfwr3yJbKgdRWIl7ZSR\r\n\t luDfrW9Uus555jRD7zbAw==" +#define SIG3 "v=1; a=rsa-sha256; c=relaxed/simple; d=example.com; s=test;\r\n\tt=1172620939; bh=yHBAX+3IwxTZIynBuB/5tlsBInJq9n8qz5fgAycHi80=;\r\n\th=Received:Received:Received:From:To:Date:Subject:Message-ID; b=hNR\r\n\tIcA7ZG6mZL9GPr5E9rJPQBy0DNnPSNAqYmtpbHJjhzWj3fsUKXDCEl8vJki6VuP0hDA\r\n\t4wRRJ6hkD0/u9iY2O+7xwAyuzkC3Z719CuGidnqlJt/1kJ4QW4KlcWJcj2v8SjD475G\r\n\tchVu0268Cz9PTJWSEqg/WZfWLQrji0gmy0=" + +/* +** FINAL -- final signature processing +** +** Parameters: +** dkim -- DKIM handle +** sigs -- array of DKIM_SIGINFO pointers +** nsigs -- how many sigs there were +** +** Return value: +** DKIM_CBSTAT_CONTINUE (assuming no assertions fire). +*/ + +DKIM_CBSTAT +final(DKIM *dkim, DKIM_SIGINFO **sigs, int nsigs) +{ + DKIM_STAT status; + u_int flags; + + assert(sigs != NULL); + assert(nsigs == 3); + + /* verify that all three signatures are okay */ + status = dkim_sig_process(dkim, sigs[0]); + assert(status == DKIM_STAT_OK); + flags = dkim_sig_getflags(sigs[0]); + assert((flags & DKIM_SIGFLAG_PROCESSED) != 0); + assert((flags & DKIM_SIGFLAG_IGNORE) == 0); + assert((flags & DKIM_SIGFLAG_PASSED) != 0); + assert(dkim_sig_getbh(sigs[0]) == DKIM_SIGBH_MATCH); + + status = dkim_sig_process(dkim, sigs[1]); + assert(status == DKIM_STAT_OK); + flags = dkim_sig_getflags(sigs[1]); + assert((flags & DKIM_SIGFLAG_PROCESSED) != 0); + assert((flags & DKIM_SIGFLAG_IGNORE) == 0); + assert((flags & DKIM_SIGFLAG_PASSED) != 0); + assert(dkim_sig_getbh(sigs[1]) == DKIM_SIGBH_MATCH); + + status = dkim_sig_process(dkim, sigs[2]); + assert(status == DKIM_STAT_OK); + flags = dkim_sig_getflags(sigs[2]); + assert((flags & DKIM_SIGFLAG_PROCESSED) != 0); + assert((flags & DKIM_SIGFLAG_IGNORE) == 0); + assert((flags & DKIM_SIGFLAG_PASSED) != 0); + assert(dkim_sig_getbh(sigs[2]) == DKIM_SIGBH_MATCH); + + return DKIM_CBSTAT_CONTINUE; +} + +/* +** MAIN -- program mainline +** +** Parameters: +** The usual. +** +** Return value: +** Exit status. +*/ + +int +main(int argc, char **argv) +{ +#ifdef TEST_KEEP_FILES + u_int flags; +#endif /* TEST_KEEP_FILES */ + DKIM_STAT status; + DKIM *dkim; + DKIM_LIB *lib; + dkim_query_t qtype = DKIM_QUERY_FILE; + unsigned char hdr[MAXHEADER + 1]; + +#ifdef USE_GNUTLS + (void) gnutls_global_init(); +#endif /* USE_GNUTLS */ + + /* instantiate the library */ + lib = dkim_init(NULL, NULL); + assert(lib != NULL); + + if (!dkim_libfeature(lib, DKIM_FEATURE_ED25519) || + !dkim_libfeature(lib, DKIM_FEATURE_SHA256)) + { + printf("*** relaxed/simple rsa-sha1/ed25519-sha256/rsa-256 verifying SKIPPED\n"); + dkim_close(lib); + return 0; + } + + printf("*** relaxed/simple rsa-sha1/ed25519-sha256/rsa-256 verifying\n"); + +#ifdef TEST_KEEP_FILES + /* set flags */ + flags = (DKIM_LIBFLAGS_TMPFILES|DKIM_LIBFLAGS_KEEPFILES); + (void) dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_FLAGS, &flags, + sizeof flags); +#endif /* TEST_KEEP_FILES */ + + (void) dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_QUERYMETHOD, + &qtype, sizeof qtype); + (void) dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_QUERYINFO, + KEYFILE, strlen(KEYFILE)); + + dkim = dkim_verify(lib, JOBID, NULL, &status); + assert(dkim != NULL); + + (void) dkim_set_final(lib, final); + + snprintf(hdr, sizeof hdr, "%s: %s", DKIM_SIGNHEADER, SIG1); + status = dkim_header(dkim, hdr, strlen(hdr)); + assert(status == DKIM_STAT_OK); + + snprintf(hdr, sizeof hdr, "%s: %s", DKIM_SIGNHEADER, SIG2); + status = dkim_header(dkim, hdr, strlen(hdr)); + assert(status == DKIM_STAT_OK); + + snprintf(hdr, sizeof hdr, "%s: %s", DKIM_SIGNHEADER, SIG3); + status = dkim_header(dkim, hdr, strlen(hdr)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER01, strlen(HEADER01)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER02, strlen(HEADER02)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER03, strlen(HEADER03)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER04, strlen(HEADER04)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER05, strlen(HEADER05)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER06, strlen(HEADER06)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER07, strlen(HEADER07)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER08, strlen(HEADER08)); + assert(status == DKIM_STAT_OK); + + status = dkim_header(dkim, HEADER09, strlen(HEADER09)); + assert(status == DKIM_STAT_OK); + + status = dkim_eoh(dkim); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY00, strlen(BODY00)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY01, strlen(BODY01)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY01A, strlen(BODY01A)); + assert(status == DKIM_STAT_OK); + status = dkim_body(dkim, BODY01B, strlen(BODY01B)); + assert(status == DKIM_STAT_OK); + status = dkim_body(dkim, BODY01C, strlen(BODY01C)); + assert(status == DKIM_STAT_OK); + status = dkim_body(dkim, BODY01D, strlen(BODY01D)); + assert(status == DKIM_STAT_OK); + status = dkim_body(dkim, BODY01E, strlen(BODY01E)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY02, strlen(BODY02)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY03, strlen(BODY03)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY04, strlen(BODY04)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY03, strlen(BODY03)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY03, strlen(BODY03)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY05, strlen(BODY05)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY03, strlen(BODY03)); + assert(status == DKIM_STAT_OK); + + status = dkim_body(dkim, BODY03, strlen(BODY03)); + assert(status == DKIM_STAT_OK); + + status = dkim_eom(dkim, NULL); + assert(status == DKIM_STAT_OK); + + status = dkim_free(dkim); + assert(status == DKIM_STAT_OK); + + dkim_close(lib); + + return 0; +} diff --git a/libopendkim/tests/t-testdata.h b/libopendkim/tests/t-testdata.h index 1fd481c5..c903c37e 100644 --- a/libopendkim/tests/t-testdata.h +++ b/libopendkim/tests/t-testdata.h @@ -25,6 +25,7 @@ #define SELECTORNOP "nop" #define SELECTOREMPTYP "emptyp" #define SELECTORCORRUPTP "corruptp" +#define SELECTORRFC8463 "rfc8463" #define DOMAIN "example.com" #define DOMAIN2 "sendmail.com" #define REPLYADDRESS "postmaster" @@ -156,6 +157,34 @@ "GKz2uWnV65RAxa1Pw352BqizqiKOBjgYGzj8pJQSs8tOvv/2k6jpI809RnESqOFg" \ "F0gu3UJbNnu3+cd8k/kiQj+q4cKKRpAT92ccxc7svhCNgN1sBGmROYZuysG3Vu3D" \ "yc079gSLtnSrgXb+gQIDAQ" + +#define RFC8463_ED25519KEY "-----BEGIN PRIVATE KEY-----\n" \ + "MC4CAQAwBQYDK2VwBCIEIJ1hsZ3v/VpguoRK9JLsLMREScVpezJpGXA7rAMcrn9g\n" \ + "-----END PRIVATE KEY-----\n" +#define RFC8463_ED25519PUBLICKEY "v=DKIM1; k=ed25519; p=" \ + "11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=" + +#define RFC8463_RSAKEY "-----BEGIN RSA PRIVATE KEY-----\n" \ + "MIICXQIBAAKBgQDkHlOQoBTzWRiGs5V6NpP3idY6Wk08a5qhdR6wy5bdOKb2jLQi\n" \ + "Y/J16JYi0Qvx/byYzCNb3W91y3FutACDfzwQ/BC/e/8uBsCR+yz1Lxj+PL6lHvqM\n" \ + "KrM3rG4hstT5QjvHO9PzoxZyVYLzBfO2EeC3Ip3G+2kryOTIKT+l/K4w3QIDAQAB\n" \ + "AoGAH0cxOhFZDgzXWhDhnAJDw5s4roOXN4OhjiXa8W7Y3rhX3FJqmJSPuC8N9vQm\n" \ + "6SVbaLAE4SG5mLMueHlh4KXffEpuLEiNp9Ss3O4YfLiQpbRqE7Tm5SxKjvvQoZZe\n" \ + "zHorimOaChRL2it47iuWxzxSiRMv4c+j70GiWdxXnxe4UoECQQDzJB/0U58W7RZy\n" \ + "6enGVj2kWF732CoWFZWzi1FicudrBFoy63QwcowpoCazKtvZGMNlPWnC7x/6o8Gc\n" \ + "uSe0ga2xAkEA8C7PipPm1/1fTRQvj1o/dDmZp243044ZNyxjg+/OPN0oWCbXIGxy\n" \ + "WvmZbXriOWoSALJTjExEgraHEgnXssuk7QJBALl5ICsYMu6hMxO73gnfNayNgPxd\n" \ + "WFV6Z7ULnKyV7HSVYF0hgYOHjeYe9gaMtiJYoo0zGN+L3AAtNP9huqkWlzECQE1a\n" \ + "licIeVlo1e+qJ6Mgqr0Q7Aa7falZ448ccbSFYEPD6oFxiOl9Y9se9iYHZKKfIcst\n" \ + "o7DUw1/hz2Ck4N5JrgUCQQCyKveNvjzkkd8HjYs0SwM0fPjK16//5qDZ2UiDGnOe\n" \ + "uEzxBDAr518Z8VFbR41in3W4Y3yCDgQlLlcETrS+zYcL\n" \ + "-----END RSA PRIVATE KEY-----\n" +#define RFC8463_RSAPUBLICKEY "v=DKIM1; k=ed25519; p=" \ + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkHlOQoBTzWR" \ + "iGs5V6NpP3idY6Wk08a5qhdR6wy5bdOKb2jLQiY/J16JYi0Qvx/byYzCNb3W91y3FutAC" \ + "DfzwQ/BC/e/8uBsCR+yz1Lxj+PL6lHvqMKrM3rG4hstT5QjvHO9PzoxZyVYLzBfO2EeC3" \ + "Ip3G+2kryOTIKT+l/K4w3QIDAQAB" + #define REPORTRECORD "ra=postmaster; rs=" SMTPTOKENENC #define GIBBERISH "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 !@#$%^&*()_+|-={}[];':,./<>?`~\r\n" diff --git a/libopendkim/tests/t-verifyperf-ed25519 b/libopendkim/tests/t-verifyperf-ed25519 new file mode 100755 index 00000000..f40169f4 --- /dev/null +++ b/libopendkim/tests/t-verifyperf-ed25519 @@ -0,0 +1,6 @@ +#!/bin/sh +# +# +# Speed verifying test using ed25519 algorithm + +./t-verifyperf -s ed25519-sha256 diff --git a/libopendkim/tests/t-verifyperf.c b/libopendkim/tests/t-verifyperf.c index a9e7a340..464439fb 100644 --- a/libopendkim/tests/t-verifyperf.c +++ b/libopendkim/tests/t-verifyperf.c @@ -10,6 +10,7 @@ /* system includes */ #include +#include #include #include #include @@ -106,6 +107,8 @@ alg_code(char *name) return (dkim_alg_t) DKIM_SIGN_RSASHA1; else if (strcasecmp(name, "rsa-sha256") == 0) return (dkim_alg_t) DKIM_SIGN_RSASHA256; + else if (strcasecmp(name, "ed25519-sha256") == 0) + return (dkim_alg_t) DKIM_SIGN_ED25519SHA256; else return (dkim_alg_t) DKIM_SIGN_UNKNOWN; } @@ -134,6 +137,9 @@ alg_name(dkim_alg_t code) case DKIM_SIGN_RSASHA256: return "rsa-sha256"; + case DKIM_SIGN_ED25519SHA256: + return "ed25519-sha256"; + case DKIM_SIGN_UNKNOWN: default: return "unknown"; @@ -195,6 +201,9 @@ main(int argc, char **argv) DKIM *dkim; DKIM_LIB *lib; dkim_sigkey_t key; + int keybits; + const char *selector; + unsigned int seed; unsigned char hdr[MAXHEADER + 1]; unsigned char body[BODYBUFRSZ]; @@ -276,8 +285,11 @@ main(int argc, char **argv) else signalg = DKIM_SIGN_RSASHA1; } - else if (signalg == DKIM_SIGN_RSASHA256 && - !dkim_libfeature(lib, DKIM_FEATURE_SHA256)) + else if ((signalg == DKIM_SIGN_RSASHA256 && + !dkim_libfeature(lib, DKIM_FEATURE_SHA256)) || + (signalg == DKIM_SIGN_ED25519SHA256 && + (!dkim_libfeature(lib, DKIM_FEATURE_ED25519) || + !dkim_libfeature(lib, DKIM_FEATURE_SHA256)))) { fprintf(stdout, "### requested signing algorithm not available\n"); @@ -285,20 +297,32 @@ main(int argc, char **argv) return 1; } - fprintf(stdout, - "*** VERIFYING SPEED TEST: %s/%s with %s, size %u for %lds\n", - canon_name(hcanon), canon_name(bcanon), alg_name(signalg), - (unsigned int) msgsize, (long) testint); + if (signalg == DKIM_SIGN_ED25519SHA256) + { + key = RFC8463_ED25519KEY; + keybits = 256; + selector = SELECTORRFC8463; + } + else + { + key = KEY; + keybits = 1024; + selector = SELECTOR; + } - key = KEY; + seed = time(NULL); + srandom(seed); + + fprintf(stdout, + "*** VERIFYING SPEED TEST: %d-bit %s/%s with %s, body size %u for %lds, random seed %u\n", + keybits, canon_name(hcanon), canon_name(bcanon), alg_name(signalg), + (unsigned int) msgsize, (long) testint, seed); (void) dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_QUERYMETHOD, &qtype, sizeof qtype); (void) dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_QUERYINFO, KEYFILE, strlen(KEYFILE)); - srandom(time(NULL)); - /* prepare a random body buffer */ for (c = 0, w = 0; c < sizeof body; c++) { @@ -314,8 +338,9 @@ main(int argc, char **argv) } /* generate the signature */ - dkim = dkim_sign(lib, JOBID, NULL, key, SELECTOR, DOMAIN, + dkim = dkim_sign(lib, JOBID, NULL, key, selector, DOMAIN, hcanon, bcanon, signalg, -1L, &status); + assert(status == DKIM_STAT_OK); status = dkim_header(dkim, HEADER02, strlen(HEADER02)); @@ -346,7 +371,7 @@ main(int argc, char **argv) msgrem -= wsz; } - status = dkim_eom(dkim, NULL); + assert(dkim_eom(dkim, NULL) == DKIM_STAT_OK); memset(hdr, '\0', sizeof hdr); snprintf(hdr, sizeof hdr, "%s: ", DKIM_SIGNHEADER); @@ -362,6 +387,7 @@ main(int argc, char **argv) while (time(NULL) < start + testint) { dkim = dkim_verify(lib, JOBID, NULL, &status); + assert(status == DKIM_STAT_OK); status = dkim_header(dkim, hdr, strlen(hdr)); @@ -395,6 +421,18 @@ main(int argc, char **argv) } status = dkim_eom(dkim, NULL); +#if 0 + if(status != DKIM_STAT_OK) + { + DKIM_SIGINFO *sig; + const char *str; + + assert((sig = dkim_getsignature(dkim)) != NULL); + str = dkim_sig_geterrorstr(dkim_sig_geterror(sig)), + fprintf(stderr, "%s\n", str); + } +#endif + assert(status == DKIM_STAT_OK); status = dkim_free(dkim);