gecko-dev/security/nss/cmd/rsaperf/rsaperf.c
nelsonb%netscape.com 920c5a1f77 The recent deletion of the SECU_Password function from cmd/lib made this
progam stop compiling.  So, as a temporary measure, to fix the build,
ifdef out the calls to the missing functions, and always behave as if
the "-n none" option had been supplied.
2001-01-07 07:46:36 +00:00

403 lines
10 KiB
C

/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#include "seccomon.h"
#include "cert.h"
#include "secutil.h"
#include "nspr.h"
#include "nss.h"
#include "blapi.h"
#include "plgetopt.h"
#define MAX_RSA_MODULUS_BYTES (1024/8)
#define DEFAULT_ITERS 10
extern SECKEYLowPrivateKey * getDefaultRSAPrivateKey(void);
extern SECKEYLowPublicKey * getDefaultRSAPublicKey(void);
typedef struct TimingContextStr TimingContext;
struct TimingContextStr {
int64 start;
int64 end;
int64 interval;
long days;
int hours;
int minutes;
int seconds;
int millisecs;
};
TimingContext *CreateTimingContext(void) {
return PR_Malloc(sizeof(TimingContext));
}
void DestroyTimingContext(TimingContext *ctx) {
PR_Free(ctx);
}
void TimingBegin(TimingContext *ctx) {
ctx->start = PR_Now();
}
static void timingUpdate(TimingContext *ctx) {
int64 tmp, remaining;
int64 L1000,L60,L24;
LL_I2L(L1000,1000);
LL_I2L(L60,60);
LL_I2L(L24,24);
LL_DIV(remaining, ctx->interval, L1000);
LL_MOD(tmp, remaining, L1000);
LL_L2I(ctx->millisecs, tmp);
LL_DIV(remaining, remaining, L1000);
LL_MOD(tmp, remaining, L60);
LL_L2I(ctx->seconds, tmp);
LL_DIV(remaining, remaining, L60);
LL_MOD(tmp, remaining, L60);
LL_L2I(ctx->minutes, tmp);
LL_DIV(remaining, remaining, L60);
LL_MOD(tmp, remaining, L24);
LL_L2I(ctx->hours, tmp);
LL_DIV(remaining, remaining, L24);
LL_L2I(ctx->days, remaining);
}
void TimingEnd(TimingContext *ctx) {
ctx->end = PR_Now();
LL_SUB(ctx->interval, ctx->end, ctx->start);
PORT_Assert(LL_GE_ZERO(ctx->interval));
timingUpdate(ctx);
}
void TimingDivide(TimingContext *ctx, int divisor) {
int64 tmp;
LL_I2L(tmp, divisor);
LL_DIV(ctx->interval, ctx->interval, tmp);
timingUpdate(ctx);
}
char *TimingGenerateString(TimingContext *ctx) {
char *buf = NULL;
if (ctx->days != 0) {
buf = PR_sprintf_append(buf, "%d days", ctx->days);
}
if (ctx->hours != 0) {
if (buf != NULL) buf = PR_sprintf_append(buf, ", ");
buf = PR_sprintf_append(buf, "%d hours", ctx->hours);
}
if (ctx->minutes != 0) {
if (buf != NULL) buf = PR_sprintf_append(buf, ", ");
buf = PR_sprintf_append(buf, "%d minutes", ctx->minutes);
}
if (buf != NULL) buf = PR_sprintf_append(buf, ", and ");
if (!buf && ctx->seconds == 0) {
int interval;
LL_L2I(interval, ctx->interval);
if (ctx->millisecs < 100)
buf = PR_sprintf_append(buf, "%d microseconds", interval);
else
buf = PR_sprintf_append(buf, "%d milliseconds", ctx->millisecs);
} else if (ctx->millisecs == 0) {
buf = PR_sprintf_append(buf, "%d seconds", ctx->seconds);
} else {
buf = PR_sprintf_append(buf, "%d.%03d seconds",
ctx->seconds, ctx->millisecs);
}
return buf;
}
void
Usage(char *progName)
{
fprintf(stderr, "Usage: %s [-d certdir] [-i iterations] [-s | -e]"
" -n nickname\n",
progName);
fprintf(stderr, "%-20s Cert database directory (default is ~/.netscape)\n",
"-d certdir");
fprintf(stderr, "%-20s How many operations to perform\n", "-i iterations");
fprintf(stderr, "%-20s Perform signing (private key) operations\n", "-s");
fprintf(stderr, "%-20s Perform encryption (public key) operations\n", "-e");
fprintf(stderr, "%-20s Nickname of certificate or key\n", "-n nickname");
exit(-1);
}
void
printCount(int iterations)
{
}
static void
dumpBytes( unsigned char * b, int l)
{
int i;
if (l <= 0)
return;
for (i = 0; i < l; ++i) {
if (i % 16 == 0)
printf("\t");
printf(" %02x", b[i]);
if (i % 16 == 15)
printf("\n");
}
if ((i % 16) != 0)
printf("\n");
}
static void
dumpItem( SECItem * item, const char * description)
{
if (item->len & 1 && item->data[0] == 0) {
printf("%s: (%d bytes)\n", description, item->len - 1);
dumpBytes(item->data + 1, item->len - 1);
} else {
printf("%s: (%d bytes)\n", description, item->len);
dumpBytes(item->data, item->len);
}
}
void
printPrivKey(SECKEYLowPrivateKey * privKey)
{
RSAPrivateKey *rsa = &privKey->u.rsa;
dumpItem( &rsa->modulus, "n");
dumpItem( &rsa->publicExponent, "e");
dumpItem( &rsa->privateExponent, "d");
dumpItem( &rsa->prime1, "P");
dumpItem( &rsa->prime2, "Q");
dumpItem( &rsa->exponent1, "d % (P-1)");
dumpItem( &rsa->exponent2, "d % (Q-1)");
dumpItem( &rsa->coefficient, "(Q ** -1) % P");
puts("");
}
void
printFnCounts(long doPrint)
{
}
typedef SECStatus (* RSAOp)(void * key,
unsigned char * output,
unsigned char * input);
int
main(int argc, char **argv)
{
TimingContext * timeCtx;
SECKEYKeyDBHandle * keydb;
SECKEYPublicKey * pubHighKey;
SECKEYLowPrivateKey * privKey;
SECKEYLowPublicKey * pubKey;
CERTCertificate * cert;
char * progName;
char * secDir = NULL;
char * nickname = NULL;
RSAOp fn;
void * rsaKey;
PLOptState * optstate;
PLOptStatus optstatus;
long iters = DEFAULT_ITERS;
int i;
PRBool doPriv = PR_FALSE;
PRBool doPub = PR_FALSE;
int rv;
CERTCertDBHandle * certdb;
unsigned char buf[1024];
unsigned char buf2[1024];
progName = strrchr(argv[0], '/');
if (!progName)
progName = strrchr(argv[0], '\\');
progName = progName ? progName+1 : argv[0];
optstate = PL_CreateOptState(argc, argv, "d:i:sen:");
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
case '?':
Usage(progName);
break;
case 'd':
secDir = PORT_Strdup(optstate->value);
break;
case 'i':
iters = atol(optstate->value);
break;
case 's':
doPriv = PR_TRUE;
break;
case 'e':
doPub = PR_TRUE;
break;
case 'n':
nickname = PORT_Strdup(optstate->value);
break;
}
}
if (optstatus == PL_OPT_BAD)
Usage(progName);
if ((doPriv && doPub) || (nickname == NULL)) Usage(progName);
if (!doPriv && !doPub) doPriv = PR_TRUE;
PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
secDir = SECU_ConfigDirectory(secDir);
if (strcmp(nickname, "none")) {
rv = NSS_Init(secDir);
if (rv != SECSuccess) {
fprintf(stderr, "NSS_Init failed.\n");
exit(1);
}
certdb = CERT_GetDefaultCertDB();
keydb = SECKEY_GetDefaultKeyDB();
} else {
rv = NSS_NoDB_Init(secDir);
if (rv != SECSuccess) {
fprintf(stderr, "NSS_NoDB_Init failed.\n");
exit(1);
}
}
#if defined(SECU_GetPassword)
if (doPub) {
if (!strcmp(nickname, "none")) {
pubKey = getDefaultRSAPublicKey();
} else {
cert = CERT_FindCertByNickname(certdb, nickname);
if (cert == NULL) {
fprintf(stderr,
"Can't find certificate by name \"%s\"\n", nickname);
exit(1);
}
pubHighKey = CERT_ExtractPublicKey(cert);
pubKey = SECU_ConvHighToLow(pubHighKey);
}
if (pubKey == NULL) {
fprintf(stderr, "Can't extract public key from certificate");
exit(1);
}
fn = (RSAOp)RSA_PublicKeyOp;
rsaKey = (void *)(&pubKey->u.rsa);
}
if (doPriv) {
if (!strcmp(nickname, "none")) {
privKey = getDefaultRSAPrivateKey();
} else {
cert = CERT_FindCertByNickname(certdb, nickname);
if (cert == NULL) {
fprintf(stderr,
"Can't find certificate by name \"%s\"\n", nickname);
exit(1);
}
privKey = SECKEY_FindKeyByCert(keydb, cert, SECU_GetPassword, NULL);
}
if (privKey == NULL) {
fprintf(stderr,
"Can't find private key by name \"%s\"\n", nickname);
exit(1);
}
#if 0
printPrivKey(privKey);
#endif
fn = (RSAOp)RSA_PrivateKeyOp;
rsaKey = (void *)(&privKey->u.rsa);
}
#else
if (doPub) {
pubKey = getDefaultRSAPublicKey();
fn = (RSAOp)RSA_PublicKeyOp;
rsaKey = (void *)(&pubKey->u.rsa);
}
if (doPriv) {
privKey = getDefaultRSAPrivateKey();
fn = (RSAOp)RSA_PrivateKeyOp;
rsaKey = (void *)(&privKey->u.rsa);
}
#endif
memset(buf, 1, sizeof buf);
rv = fn(rsaKey, buf2, buf);
if (rv != SECSuccess) {
PRErrorCode errNum;
const char * errStr = NULL;
errNum = PR_GetError();
if (errNum)
errStr = SECU_Strerror(errNum);
else
errNum = rv;
if (!errStr)
errStr = "(null)";
fprintf(stderr, "Error in RSA operation: %d : %s\n", errNum, errStr);
exit(1);
}
/* printf("START\n"); */
timeCtx = CreateTimingContext();
TimingBegin(timeCtx);
i = iters;
while (i--) {
rv = fn(rsaKey, buf2, buf);
if (rv != SECSuccess) {
PRErrorCode errNum = PR_GetError();
const char * errStr = SECU_Strerror(errNum);
fprintf(stderr, "Error in RSA operation: %d : %s\n",
errNum, errStr);
exit(1);
}
}
TimingEnd(timeCtx);
printf("%ld iterations in %s\n",
iters, TimingGenerateString(timeCtx));
TimingDivide(timeCtx, iters);
printf("one operation every %s\n", TimingGenerateString(timeCtx));
return 0;
}