Back to index

opendkim  2.6.6
t-signperf.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_signperf_c_id[] = "@(#)$Id: t-signperf.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 "t-testdata.h"
00030 
00031 #define       DEFMSGSIZE    1024
00032 #define       DEFTESTINT    5
00033 #define       BODYBUFRSZ    8192
00034 #define       MAXHEADER     4096
00035 
00036 #ifndef MIN
00037 # define MIN(x,y)    ((x) < (y) ? (x) : (y))
00038 #endif /* ! MIN */
00039 
00040 char *progname;
00041 
00042 /*
00043 **  CANON_CODE -- convert a canonicalization name to its code
00044 **
00045 **  Parameters:
00046 **     name -- name to convert
00047 **
00048 **  Return value:
00049 **     dkim_canon_t
00050 */
00051 
00052 dkim_canon_t
00053 canon_code(char *name)
00054 {
00055        if (name == NULL)
00056               return (dkim_canon_t) DKIM_CANON_UNKNOWN;
00057        else if (strcasecmp(name, "simple") == 0)
00058               return (dkim_canon_t) DKIM_CANON_SIMPLE;
00059        else if (strcasecmp(name, "relaxed") == 0)
00060               return (dkim_canon_t) DKIM_CANON_RELAXED;
00061        else
00062               return (dkim_canon_t) DKIM_CANON_UNKNOWN;
00063 }
00064 
00065 /*
00066 **  CANON_NAME -- convert a canonicalization code to its name
00067 **
00068 **  Parameters:
00069 **     code -- code to convert
00070 **
00071 **  Return value:
00072 **     Pointer to name string.
00073 */
00074 
00075 char *
00076 canon_name(dkim_canon_t code)
00077 {
00078        switch (code)
00079        {
00080          case DKIM_CANON_SIMPLE:
00081               return "simple";
00082 
00083          case DKIM_CANON_RELAXED:
00084               return "relaxed";
00085 
00086          case DKIM_CANON_UNKNOWN:
00087          default:
00088               return "unknown";
00089        }
00090 }
00091 
00092 /*
00093 **  ALG_CODE -- convert an algorithm name to its code
00094 **
00095 **  Parameters:
00096 **     name -- name to convert
00097 **
00098 **  Return value:
00099 **     dkim_alg_t
00100 */
00101 
00102 dkim_alg_t
00103 alg_code(char *name)
00104 {
00105        if (name == NULL)
00106               return (dkim_alg_t) DKIM_SIGN_UNKNOWN;
00107        else if (strcasecmp(name, "rsa-sha1") == 0)
00108               return (dkim_alg_t) DKIM_SIGN_RSASHA1;
00109        else if (strcasecmp(name, "rsa-sha256") == 0)
00110               return (dkim_alg_t) DKIM_SIGN_RSASHA256;
00111        else
00112               return (dkim_alg_t) DKIM_SIGN_UNKNOWN;
00113 }
00114 
00115 /*
00116 **  ALG_NAME -- convert an algorithm code to its name
00117 **
00118 **  Parameters:
00119 **     code -- code to convert
00120 **
00121 **  Return value:
00122 **     Pointer to name string.
00123 */
00124 
00125 char *
00126 alg_name(dkim_alg_t code)
00127 {
00128        switch (code)
00129        {
00130          case DKIM_SIGN_DEFAULT:
00131               return "default";
00132 
00133          case DKIM_SIGN_RSASHA1:
00134               return "rsa-sha1";
00135 
00136          case DKIM_SIGN_RSASHA256:
00137               return "rsa-sha256";
00138 
00139          case DKIM_SIGN_UNKNOWN:
00140          default:
00141               return "unknown";
00142        }
00143 }
00144 
00145 /*
00146 **  USAGE -- print usage message
00147 **
00148 **  Parameters:
00149 **     None.
00150 **
00151 **  Return value:
00152 **     EX_USAGE
00153 */
00154 
00155 int
00156 usage(void)
00157 {
00158        fprintf(stderr, "%s: usage: %s [options]\n"
00159                "\t-b bodycanon\tbody canonicalization to use\n"
00160                "\t-h hdrcanon \theader canonicalization to use\n"
00161                "\t-m bytes    \tmessage size in bytes\n"
00162                "\t-s signalg  \tsigning algorithm to use\n"
00163                "\t-t seconds  \ttest time in seconds\n",
00164                progname, progname);
00165 
00166        return EX_USAGE;
00167 }
00168 
00169 /*
00170 **  MAIN -- program mainline
00171 **
00172 **  Parameters:
00173 **     The usual.
00174 **
00175 **  Return value:
00176 **     Exit status.
00177 */
00178 
00179 int
00180 main(int argc, char **argv)
00181 {
00182        DKIM_STAT status;
00183        u_int signcnt = 0;
00184        int c;
00185        int w;
00186        int rate;
00187        size_t msgsize = DEFMSGSIZE;
00188        size_t msgrem;
00189        size_t wsz;
00190        char *p;
00191        DKIM *dkim;
00192        DKIM_LIB *lib;
00193        dkim_sigkey_t key;
00194        unsigned char hdr[MAXHEADER + 1];
00195        unsigned char body[BODYBUFRSZ];
00196        time_t start = DEFTESTINT;
00197        time_t testint = DEFTESTINT;
00198        dkim_canon_t hcanon = DKIM_CANON_RELAXED;
00199        dkim_canon_t bcanon = DKIM_CANON_SIMPLE;
00200        dkim_alg_t signalg = DKIM_SIGN_UNKNOWN;
00201 
00202        progname = (p = strrchr(argv[0], '/')) == NULL ? argv[0] : p + 1;
00203 
00204        while ((c = getopt(argc, argv, "b:h:m:s:t:")) != -1)
00205        {
00206               switch (c)
00207               {
00208                 case 'b':
00209                      bcanon = canon_code(optarg);
00210                      if (bcanon == (dkim_canon_t) -1)
00211                      {
00212                             fprintf(stderr,
00213                                     "%s: unknown canonicalization '%s'\n",
00214                                     progname, optarg);
00215                             return EX_USAGE;
00216                      }
00217                      break;
00218 
00219                 case 'h':
00220                      hcanon = canon_code(optarg);
00221                      if (hcanon == (dkim_canon_t) -1)
00222                      {
00223                             fprintf(stderr,
00224                                     "%s: unknown canonicalization '%s'\n",
00225                                     progname, optarg);
00226                             return EX_USAGE;
00227                      }
00228                      break;
00229 
00230                 case 'm':
00231                      msgsize = strtoul(optarg, &p, 10);
00232                      if (*p != '\0')
00233                      {
00234                             fprintf(stderr, "%s: invalid size '%s'\n",
00235                                     progname, optarg);
00236                             return EX_USAGE;
00237                      }
00238                      break;
00239 
00240                 case 's':
00241                      signalg = alg_code(optarg);
00242                      if (signalg == (dkim_alg_t) -1)
00243                      {
00244                             fprintf(stderr,
00245                                     "%s: unknown signing algorithm '%s'\n",
00246                                     progname, optarg);
00247                             return EX_USAGE;
00248                      }
00249                      break;
00250 
00251                 case 't':
00252                      testint = strtoul(optarg, &p, 10);
00253                      if (*p != '\0')
00254                      {
00255                             fprintf(stderr, "%s: invalid seconds '%s'\n",
00256                                     progname, optarg);
00257                             return EX_USAGE;
00258                      }
00259                      break;
00260 
00261                 default:
00262                      return usage();
00263               }
00264        }
00265 
00266 #ifdef USE_GNUTLS
00267        (void) gnutls_global_init();
00268 #endif /* USE_GNUTLS */
00269 
00270        /* instantiate the library */
00271        lib = dkim_init(NULL, NULL);
00272 
00273        if (signalg == DKIM_SIGN_UNKNOWN)
00274        {
00275               if (dkim_libfeature(lib, DKIM_FEATURE_SHA256))
00276                      signalg = DKIM_SIGN_RSASHA256;
00277               else
00278                      signalg = DKIM_SIGN_RSASHA1;
00279        }
00280        else if (signalg == DKIM_SIGN_RSASHA256 &&
00281                 !dkim_libfeature(lib, DKIM_FEATURE_SHA256))
00282        {
00283               fprintf(stdout,
00284                       "### requested signing algorithm not available\n");
00285               dkim_close(lib);
00286               return 1;
00287        }
00288 
00289        fprintf(stdout,
00290                "*** SIGNING SPEED TEST: %s/%s with %s, size %u for %lds\n",
00291                canon_name(hcanon), canon_name(bcanon), alg_name(signalg),
00292                msgsize, (long) testint);
00293 
00294        key = KEY;
00295 
00296        srandom(time(NULL));
00297 
00298        /* prepare a random body buffer */
00299        for (c = 0, w = 0; c < sizeof body; c++)
00300        {
00301               if (w >= 75 && c < sizeof body - 2)
00302               {
00303                      body[c++] = '\r';
00304                      body[c++] = '\n';
00305                      w = 0;
00306               }
00307 
00308               body[c] = (random() % 95) + 32;
00309               w++;
00310        }
00311 
00312        (void) time(&start);
00313 
00314        while (time(NULL) < start + testint)
00315        {
00316               dkim = dkim_sign(lib, JOBID, NULL, key, SELECTOR, DOMAIN,
00317                                hcanon, bcanon, signalg, -1L, &status);
00318 
00319               status = dkim_header(dkim, HEADER02, strlen(HEADER02));
00320 
00321               status = dkim_header(dkim, HEADER03, strlen(HEADER03));
00322 
00323               status = dkim_header(dkim, HEADER04, strlen(HEADER04));
00324 
00325               status = dkim_header(dkim, HEADER05, strlen(HEADER05));
00326 
00327               status = dkim_header(dkim, HEADER06, strlen(HEADER06));
00328 
00329               status = dkim_header(dkim, HEADER07, strlen(HEADER07));
00330 
00331               status = dkim_header(dkim, HEADER08, strlen(HEADER08));
00332 
00333               status = dkim_header(dkim, HEADER09, strlen(HEADER09));
00334 
00335               status = dkim_eoh(dkim);
00336 
00337               msgrem = msgsize;
00338 
00339               while (msgrem > 0)
00340               {
00341                      wsz = MIN(msgrem, sizeof body);
00342 
00343                      status = dkim_body(dkim, body, wsz);
00344 
00345                      msgrem -= wsz;
00346               }
00347 
00348               (void) dkim_body(dkim, CRLF, 2);
00349 
00350               status = dkim_eom(dkim, NULL);
00351 
00352               memset(hdr, '\0', sizeof hdr);
00353               status = dkim_getsighdr(dkim, hdr, sizeof hdr,
00354                                       strlen(DKIM_SIGNHEADER) + 2);
00355 
00356               status = dkim_free(dkim);
00357 
00358               signcnt++;
00359        }
00360 
00361        dkim_close(lib);
00362 
00363        rate = signcnt / testint;
00364 
00365        fprintf(stdout, "*** %u messages signed (%d msgs/sec)\n",
00366                signcnt, rate);
00367 
00368        return 0;
00369 }