Back to index

opendkim  2.6.2
t-verifyperf.c
Go to the documentation of this file.
00001 /*
00002 **  Copyright (c) 2005-2008 Sendmail, Inc. and its suppliers.
00003 **    All rights reserved.
00004 **
00005 **  Copyright (c) 2009, 2011, The OpenDKIM Project.  All rights reserved.
00006 */
00007 
00008 #ifndef lint
00009 static char t_verifyperf_c_id[] = "@(#)$Id: t-verifyperf.c,v 1.2 2009/12/08 19:14:27 cm-msk Exp $";
00010 #endif /* !lint */
00011 
00012 #include "build-config.h"
00013 
00014 /* system includes */
00015 #include <sys/types.h>
00016 #include <stdio.h>
00017 #include <stdlib.h>
00018 #include <string.h>
00019 #include <time.h>
00020 #include <unistd.h>
00021 #include <sysexits.h>
00022 
00023 #ifdef USE_GNUTLS
00024 # include <gnutls/gnutls.h>
00025 #endif /* USE_GNUTLS */
00026 
00027 /* libopendkim includes */
00028 #include "../dkim.h"
00029 #include "../dkim-tables.h"
00030 #include "t-testdata.h"
00031 
00032 #define       DEFMSGSIZE    1024
00033 #define       DEFTESTINT    5
00034 #define       BODYBUFRSZ    8192
00035 #define       MAXHEADER     4096
00036 
00037 #ifndef MIN
00038 # define MIN(x,y)    ((x) < (y) ? (x) : (y))
00039 #endif /* ! MIN */
00040 
00041 char *progname;
00042 
00043 /*
00044 **  CANON_CODE -- convert a canonicalization name to its code
00045 **
00046 **  Parameters:
00047 **     name -- name to convert
00048 **
00049 **  Return value:
00050 **     dkim_canon_t
00051 */
00052 
00053 dkim_canon_t
00054 canon_code(char *name)
00055 {
00056        if (name == NULL)
00057               return (dkim_canon_t) DKIM_CANON_UNKNOWN;
00058        else if (strcasecmp(name, "simple") == 0)
00059               return (dkim_canon_t) DKIM_CANON_SIMPLE;
00060        else if (strcasecmp(name, "relaxed") == 0)
00061               return (dkim_canon_t) DKIM_CANON_RELAXED;
00062        else
00063               return (dkim_canon_t) DKIM_CANON_UNKNOWN;
00064 }
00065 
00066 /*
00067 **  CANON_NAME -- convert a canonicalization code to its name
00068 **
00069 **  Parameters:
00070 **     code -- code to convert
00071 **
00072 **  Return value:
00073 **     Pointer to name string.
00074 */
00075 
00076 char *
00077 canon_name(dkim_canon_t code)
00078 {
00079        switch (code)
00080        {
00081          case DKIM_CANON_SIMPLE:
00082               return "simple";
00083 
00084          case DKIM_CANON_RELAXED:
00085               return "relaxed";
00086 
00087          case DKIM_CANON_UNKNOWN:
00088          default:
00089               return "unknown";
00090        }
00091 }
00092 
00093 /*
00094 **  ALG_CODE -- convert an algorithm name to its code
00095 **
00096 **  Parameters:
00097 **     name -- name to convert
00098 **
00099 **  Return value:
00100 **     dkim_alg_t
00101 */
00102 
00103 dkim_alg_t
00104 alg_code(char *name)
00105 {
00106        if (name == NULL)
00107               return (dkim_alg_t) DKIM_SIGN_UNKNOWN;
00108        else if (strcasecmp(name, "rsa-sha1") == 0)
00109               return (dkim_alg_t) DKIM_SIGN_RSASHA1;
00110        else if (strcasecmp(name, "rsa-sha256") == 0)
00111               return (dkim_alg_t) DKIM_SIGN_RSASHA256;
00112        else
00113               return (dkim_alg_t) DKIM_SIGN_UNKNOWN;
00114 }
00115 
00116 /*
00117 **  ALG_NAME -- convert an algorithm code to its name
00118 **
00119 **  Parameters:
00120 **     code -- code to convert
00121 **
00122 **  Return value:
00123 **     Pointer to name string.
00124 */
00125 
00126 char *
00127 alg_name(dkim_alg_t code)
00128 {
00129        switch (code)
00130        {
00131          case DKIM_SIGN_DEFAULT:
00132               return "default";
00133 
00134          case DKIM_SIGN_RSASHA1:
00135               return "rsa-sha1";
00136 
00137          case DKIM_SIGN_RSASHA256:
00138               return "rsa-sha256";
00139 
00140          case DKIM_SIGN_UNKNOWN:
00141          default:
00142               return "unknown";
00143        }
00144 }
00145 
00146 /*
00147 **  USAGE -- print usage message
00148 **
00149 **  Parameters:
00150 **     None.
00151 **
00152 **  Return value:
00153 **     EX_USAGE
00154 */
00155 
00156 int
00157 usage(void)
00158 {
00159        fprintf(stderr, "%s: usage: %s [options]\n"
00160                "\t-b bodycanon\tbody canonicalization to use\n"
00161                "\t-h hdrcanon \theader canonicalization to use\n"
00162                "\t-m bytes    \tmessage size in bytes\n"
00163                "\t-s signalg  \tsigning algorithm to use\n"
00164                "\t-t seconds  \ttest time in seconds\n",
00165                progname, progname);
00166 
00167        return EX_USAGE;
00168 }
00169 
00170 /*
00171 **  MAIN -- program mainline
00172 **
00173 **  Parameters:
00174 **     The usual.
00175 **
00176 **  Return value:
00177 **     Exit status.
00178 */
00179 
00180 int
00181 main(int argc, char **argv)
00182 {
00183        DKIM_STAT status;
00184        u_int verifycnt = 0;
00185        int c;
00186        int w;
00187        int rate;
00188        size_t msgsize = DEFMSGSIZE;
00189        size_t msgrem;
00190        size_t wsz;
00191        time_t start = DEFTESTINT;
00192        time_t testint = DEFTESTINT;
00193        dkim_canon_t hcanon = DKIM_CANON_RELAXED;
00194        dkim_canon_t bcanon = DKIM_CANON_SIMPLE;
00195        dkim_alg_t signalg = DKIM_SIGN_UNKNOWN;
00196        dkim_query_t qtype = DKIM_QUERY_FILE;
00197        char *p;
00198        DKIM *dkim;
00199        DKIM_LIB *lib;
00200        dkim_sigkey_t key;
00201        unsigned char hdr[MAXHEADER + 1];
00202        unsigned char body[BODYBUFRSZ];
00203 
00204        progname = (p = strrchr(argv[0], '/')) == NULL ? argv[0] : p + 1;
00205 
00206        while ((c = getopt(argc, argv, "b:h:m:s:t:")) != -1)
00207        {
00208               switch (c)
00209               {
00210                 case 'b':
00211                      bcanon = canon_code(optarg);
00212                      if (bcanon == (dkim_canon_t) -1)
00213                      {
00214                             fprintf(stderr,
00215                                     "%s: unknown canonicalization '%s'\n",
00216                                     progname, optarg);
00217                             return EX_USAGE;
00218                      }
00219                      break;
00220 
00221                 case 'h':
00222                      hcanon = canon_code(optarg);
00223                      if (hcanon == (dkim_canon_t) -1)
00224                      {
00225                             fprintf(stderr,
00226                                     "%s: unknown canonicalization '%s'\n",
00227                                     progname, optarg);
00228                             return EX_USAGE;
00229                      }
00230                      break;
00231 
00232                 case 'm':
00233                      msgsize = strtoul(optarg, &p, 10);
00234                      if (*p != '\0')
00235                      {
00236                             fprintf(stderr, "%s: invalid size '%s'\n",
00237                                     progname, optarg);
00238                             return EX_USAGE;
00239                      }
00240                      break;
00241 
00242                 case 's':
00243                      signalg = alg_code(optarg);
00244                      if (signalg == (dkim_alg_t) -1)
00245                      {
00246                             fprintf(stderr,
00247                                     "%s: unknown signing algorithm '%s'\n",
00248                                     progname, optarg);
00249                             return EX_USAGE;
00250                      }
00251                      break;
00252 
00253                 case 't':
00254                      testint = strtoul(optarg, &p, 10);
00255                      if (*p != '\0')
00256                      {
00257                             fprintf(stderr, "%s: invalid seconds '%s'\n",
00258                                     progname, optarg);
00259                             return EX_USAGE;
00260                      }
00261                      break;
00262 
00263                 default:
00264                      return usage();
00265               }
00266        }
00267 
00268 #ifdef USE_GNUTLS
00269        (void) gnutls_global_init();
00270 #endif /* USE_GNUTLS */
00271 
00272        /* instantiate the library */
00273        lib = dkim_init(NULL, NULL);
00274 
00275        if (signalg == DKIM_SIGN_UNKNOWN)
00276        {
00277               if (dkim_libfeature(lib, DKIM_FEATURE_SHA256))
00278                      signalg = DKIM_SIGN_RSASHA256;
00279               else
00280                      signalg = DKIM_SIGN_RSASHA1;
00281        }
00282        else if (signalg == DKIM_SIGN_RSASHA256 &&
00283                 !dkim_libfeature(lib, DKIM_FEATURE_SHA256))
00284        {
00285               fprintf(stdout,
00286                       "### requested signing algorithm not available\n");
00287               dkim_close(lib);
00288               return 1;
00289        }
00290 
00291        fprintf(stdout,
00292                "*** VERIFYING SPEED TEST: %s/%s with %s, size %u for %lds\n",
00293                canon_name(hcanon), canon_name(bcanon), alg_name(signalg),
00294                msgsize, (long) testint);
00295 
00296        key = KEY;
00297 
00298        (void) dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_QUERYMETHOD,
00299                            &qtype, sizeof qtype);
00300        (void) dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_QUERYINFO,
00301                            KEYFILE, strlen(KEYFILE));
00302 
00303        srandom(time(NULL));
00304 
00305        /* prepare a random body buffer */
00306        for (c = 0, w = 0; c < sizeof body; c++)
00307        {
00308               if (w >= 75 && c < sizeof body - 2)
00309               {
00310                      body[c++] = '\r';
00311                      body[c++] = '\n';
00312                      w = 0;
00313               }
00314 
00315               body[c++] = (random() + 32) % 127;
00316               w++;
00317        }
00318 
00319        /* generate the signature */
00320        dkim = dkim_sign(lib, JOBID, NULL, key, SELECTOR, DOMAIN,
00321                         hcanon, bcanon, signalg, -1L, &status);
00322 
00323        status = dkim_header(dkim, HEADER02, strlen(HEADER02));
00324 
00325        status = dkim_header(dkim, HEADER03, strlen(HEADER03));
00326 
00327        status = dkim_header(dkim, HEADER04, strlen(HEADER04));
00328 
00329        status = dkim_header(dkim, HEADER05, strlen(HEADER05));
00330 
00331        status = dkim_header(dkim, HEADER06, strlen(HEADER06));
00332 
00333        status = dkim_header(dkim, HEADER07, strlen(HEADER07));
00334 
00335        status = dkim_header(dkim, HEADER08, strlen(HEADER08));
00336 
00337        status = dkim_header(dkim, HEADER09, strlen(HEADER09));
00338 
00339        status = dkim_eoh(dkim);
00340 
00341        msgrem = msgsize;
00342 
00343        while (msgrem > 0)
00344        {
00345               wsz = MIN(msgrem, sizeof body);
00346 
00347               status = dkim_body(dkim, body, wsz);
00348 
00349               msgrem -= wsz;
00350        }
00351 
00352        status = dkim_eom(dkim, NULL);
00353 
00354        memset(hdr, '\0', sizeof hdr);
00355        snprintf(hdr, sizeof hdr, "%s: ", DKIM_SIGNHEADER);
00356        status = dkim_getsighdr(dkim, hdr + strlen(hdr),
00357                                sizeof hdr - strlen(hdr),
00358                                strlen(hdr) + 1);
00359 
00360        status = dkim_free(dkim);
00361 
00362        (void) time(&start);
00363 
00364        /* begin the verify loop */
00365        while (time(NULL) < start + testint)
00366        {
00367               dkim = dkim_verify(lib, JOBID, NULL, &status);
00368 
00369               status = dkim_header(dkim, hdr, strlen(hdr));
00370 
00371               status = dkim_header(dkim, HEADER02, strlen(HEADER02));
00372 
00373               status = dkim_header(dkim, HEADER03, strlen(HEADER03));
00374 
00375               status = dkim_header(dkim, HEADER04, strlen(HEADER04));
00376 
00377               status = dkim_header(dkim, HEADER05, strlen(HEADER05));
00378 
00379               status = dkim_header(dkim, HEADER06, strlen(HEADER06));
00380 
00381               status = dkim_header(dkim, HEADER07, strlen(HEADER07));
00382 
00383               status = dkim_header(dkim, HEADER08, strlen(HEADER08));
00384 
00385               status = dkim_header(dkim, HEADER09, strlen(HEADER09));
00386 
00387               status = dkim_eoh(dkim);
00388 
00389               msgrem = DEFMSGSIZE;
00390 
00391               while (msgrem > 0)
00392               {
00393                      wsz = MIN(msgrem, sizeof body);
00394 
00395                      status = dkim_body(dkim, body, wsz);
00396 
00397                      msgrem -= wsz;
00398               }
00399 
00400               status = dkim_eom(dkim, NULL);
00401 
00402               status = dkim_free(dkim);
00403 
00404               verifycnt++;
00405        }
00406 
00407        dkim_close(lib);
00408 
00409        rate = verifycnt / testint;
00410 
00411        fprintf(stdout, "*** %u messages verified (%d msgs/sec)\n",
00412                verifycnt, rate);
00413 
00414        return 0;
00415 }