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);