blapitest.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,834 行 · 第 1/4 页

C
1,834
字号
	"des_ecb",	"des_cbc",	"des3_ecb",	"des3_cbc",	"rc2_ecb",	"rc2_cbc",	"rc4",#if NSS_SOFTOKEN_DOES_RC5	"rc5_ecb",	"rc5_cbc",#endif	"rsa",	"#endencrypt",	"pqg",	"dsa",	"#endsign",	"md5",	"md2",	"sha1",	"#endhash"};static voidprintmodes(blapitestInfo *info){	int i = 0;	char *mode = mode_strings[0];	PR_fprintf(PR_STDERR, "Available modes: (specify with -m)\n", progName);	while (mode[0] != '#') {		if (info->encrypt || info->decrypt)			fprintf(stderr, "%s\n", mode);		mode = mode_strings[++i];	}	mode = mode_strings[++i];	while (mode[0] != '#') {		if (info->sign || info->verify)			fprintf(stderr, "%s\n", mode);		mode = mode_strings[++i];	}	mode = mode_strings[++i];	while (mode[0] != '#') {		if (info->hash)			fprintf(stderr, "%s\n", mode);		mode = mode_strings[++i];	}}static blapitestCryptoFnget_test_mode(const char *modestring){	int i;	int nummodes = sizeof(mode_strings) / sizeof(char *);	for (i=0; i<nummodes; i++)		if (PL_strcmp(modestring, mode_strings[i]) == 0)			return crypto_fns[i];	PR_fprintf(PR_STDERR, "%s: invalid mode: %s\n", progName, modestring);	return NULL;}static voidget_params(blapitestInfo *info, char *mode, int num){	SECItem *item;	/* XXX	 * this should use NSPR, but the string functions (strchr and atoi)	 * barf when the commented code below is used.	PRFileDesc *file;	*/	FILE *file;	char filename[256];	char *mark, *param, *val;	int index = 0;	int len;	sprintf(filename, "%s/tests/%s/params%d", testdir, mode, num);	/*	file = PR_Open(filename, PR_RDONLY, 00440);	if (file)		SECU_FileToItem(item, file);	else		return;	param = (char *)item->data;	*/	file = fopen(filename, "r");	if (!file) return;	param = malloc(100);	len = fread(param, 1, 100, file);	while (index < len) {		mark = PL_strchr(param, '=');		*mark = '\0';		val = mark + 1;		mark = PL_strchr(val, '\n');		*mark = '\0';		if (PL_strcmp(param, "rounds") == 0) {			info->rounds = atoi(val);		} else if (PL_strcmp(param, "wordsize") == 0) {			info->wordsize = atoi(val);		}		index += PL_strlen(param) + PL_strlen(val) + 2;		param = mark + 1;	}}static SECStatusget_ascii_file_data(SECItem *item, char *mode, char *type, int num){	char filename[256];	PRFileDesc *file;	SECStatus rv;	sprintf(filename, "%s/tests/%s/%s%d", testdir, mode, type, num);	file = PR_Open(filename, PR_RDONLY, 00440);	if (!file) {		/* Not a failure if "mode" does not need "type". */		return SECSuccess;	}	if (((PL_strcmp(mode, "rsa") == 0 || PL_strcmp(mode, "dsa") == 0) && 	      PL_strcmp(type, "key") == 0) ||	   (PL_strcmp(mode, "dsa") == 0 && PL_strcmp(type, "plaintext") == 0)) {		rv = SECU_FileToItem(item, file);		atob(SECITEM_DupItem(item), item);	} else {		rv = SECU_TextFileToItem(item, file);	}	PR_Close(file);	return rv;}static SECStatusblapi_selftest(char **modesToTest, int numModesToTest,                PRBool encrypt, PRBool decrypt){	blapitestCryptoFn cryptofn;	blapitestInfo info;	SECItem output = { 0, 0, 0 };	SECItem asciiOut = { 0, 0, 0 };	SECItem inpCopy = { 0, 0, 0 };	SECItem item = { 0, 0, 0 };	SECStatus rv;	char filename[256];	PRFileDesc *file;	char *mode;	int i, j, nummodes;	PORT_Memset(&info, 0, sizeof(info));	info.repetitions = 1;	info.useseed = PR_TRUE;	info.usesigseed = PR_TRUE;	if (modesToTest) {		/* user gave a list of modes to test */		nummodes = numModesToTest;	} else {		/* test all modes */		nummodes = sizeof(mode_strings) / sizeof(char *);	}	for (i=0; i<nummodes; i++) {		if (modesToTest) {			mode = modesToTest[i];		} else {			mode = mode_strings[i];		}		/* skip pqg - nothing to do for self-test. */		if (PL_strcmp(mode, "pqg") == 0)			continue;		cryptofn = get_test_mode(mode);		if (mode[0] == '#') continue;		/* get the number of tests in the directory */		sprintf(filename, "%s/tests/%s/%s", testdir, mode, "numtests");		file = PR_Open(filename, PR_RDONLY, 00440);		if (!file) {			fprintf(stderr, "File %s does not exist.\n", filename);			return SECFailure;		}		memset(&item, 0, sizeof(item));		rv = SECU_FileToItem(&item, file);		PR_Close(file);		/* loop over the tests in the directory */		for (j=0; j<(int)(item.data[0] - '0'); j++) {			memset(&info.key, 0, sizeof(info.key));			memset(&info.iv, 0, sizeof(info.iv));			memset(&info.in, 0, sizeof(info.in));			memset(&info.seed, 0, sizeof(info.seed));			memset(&info.sigseed, 0, sizeof(info.sigseed));			rv = get_ascii_file_data(&info.key, mode, "key", j);			rv = get_ascii_file_data(&info.iv, mode, "iv", j);			rv = get_ascii_file_data(&info.in, mode, "plaintext", j);#if 0			rv = get_ascii_file_data(&info.seed, mode, "keyseed", j);#endif			rv = get_ascii_file_data(&info.sigseed, mode, "sigseed", j);			SECITEM_CopyItem(NULL, &inpCopy, &info.in);			get_params(&info, mode, j);			sprintf(filename, "%s/tests/%s/%s%d", testdir, mode, 			        "ciphertext", j);			file = PR_Open(filename, PR_RDONLY, 00440);			memset(&asciiOut, 0, sizeof(asciiOut));			rv = SECU_FileToItem(&asciiOut, file);			PR_Close(file);			rv = atob(&asciiOut, &output);			if (!encrypt) goto decrypt;			info.encrypt = info.hash = info.sign = PR_TRUE;			(*cryptofn)(&info);			if (SECITEM_CompareItem(&output, &info.out) != 0) {				printf("encrypt self-test for %s failed!\n", mode);			} /*else {				printf("encrypt self-test for %s passed.\n", mode);			}*/decrypt:			if (!decrypt) continue;			if (PL_strcmp(mode, "md2") == 0 ||			    PL_strcmp(mode, "md5") == 0 ||			    PL_strcmp(mode, "sha1") == 0) {				continue; /* hashes only go once */			}			info.encrypt = info.hash = info.sign = PR_FALSE;			info.decrypt = info.verify = PR_TRUE;			if (PL_strcmp(mode, "dsa") == 0) {				if (info.out.len == 0)				    SECITEM_CopyItem(NULL, &info.out, &output);				rv = (*cryptofn)(&info);				if (rv != SECSuccess) {					printf("signature self-test for %s failed!\n", mode);				} /*else {					printf("signature self-test for %s passed.\n", mode);				}*/			} else {				SECITEM_ZfreeItem(&info.in, PR_FALSE);				SECITEM_ZfreeItem(&info.out, PR_FALSE);				SECITEM_CopyItem(NULL, &info.in, &output);				info.out.len = 0;				rv = (*cryptofn)(&info);				if (rv == SECSuccess) {					if (SECITEM_CompareItem(&inpCopy, &info.out) != 0) {						printf("decrypt self-test for %s failed!\n", mode);					} /*else {						printf("decrypt self-test for %s passed.\n", mode);					}*/				}			}		}	}	return SECSuccess;}static SECStatusget_file_data(char *filename, SECItem *item, PRBool b64) {	SECStatus rv = SECSuccess;	PRFileDesc *file = PR_Open(filename, PR_RDONLY, 006600);	if (file) {		if (b64) {			SECItem asciiItem = { 0, 0, 0 };			rv = SECU_FileToItem(&asciiItem, file);			CHECKERROR(rv, __LINE__);			rv = atob(&asciiItem, item);		} else {			rv = SECU_FileToItem(item, file);			CHECKERROR(rv, __LINE__);		}		CHECKERROR(rv, __LINE__);		PR_Close(file);	}	return rv;}SECStatusdump_file(char *mode, char *filename){	SECItem item;	if (PL_strcmp(mode, "rsa") == 0) {	} else if (PL_strcmp(mode, "pqg") == 0) {		PQGParams *pqg;		get_file_data(filename, &item, PR_TRUE);		pqg = pqg_from_filedata(&item);		dump_pqg(pqg);	} else if (PL_strcmp(mode, "dsa") == 0) {		DSAPrivateKey *key;		get_file_data(filename, &item, PR_TRUE);		key = dsakey_from_filedata(&item);		dump_dsakey(key);	}	return SECFailure;}int main(int argc, char **argv) {	char *infile, *outfile, *keyfile, *ivfile, *sigfile, *seedfile,	     *sigseedfile, *pqgfile;	PRBool b64 = PR_TRUE;	blapitestInfo info;	blapitestCryptoFn cryptofn = NULL;	PLOptState *optstate;	PLOptStatus status;	PRBool dofips = PR_FALSE;	PRBool doselftest = PR_FALSE;	PRBool zerobuffer = PR_FALSE;	char *dumpfile = NULL;	char *mode = NULL;	char *modesToTest[20];	int numModesToTest = 0;	SECStatus rv;	PORT_Memset(&info, 0, sizeof(info));	info.bufsize = 8;	info.keysize = DES_KEY_LENGTH;	info.rsapubexp = 17;	info.rounds = 10;	info.wordsize = 4;	infile=outfile=keyfile=pqgfile=ivfile=sigfile=seedfile=sigseedfile=NULL;	info.repetitions = 1;    progName = strrchr(argv[0], '/');    progName = progName ? progName+1 : argv[0];	optstate = PL_CreateOptState(argc, argv, 	    "DEFHP:STVab:d:ce:g:j:i:o:p:k:m:t:qr:s:v:w:xyz:");	while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {		switch (optstate->option) {		case 'D':  info.decrypt = PR_TRUE; break;		case 'E':  info.encrypt = PR_TRUE; break;		case 'F':  dofips = PR_TRUE; break;		case 'H':  info.hash = PR_TRUE; break;		case 'P':  dumpfile = PL_strdup(optstate->value); break;		case 'S':  info.sign = PR_TRUE; break;		case 'T':  doselftest = PR_TRUE; break;		case 'V':  info.verify = PR_TRUE; break;		case 'a':  b64 = PR_FALSE; break;		case 'b':  info.bufsize = PORT_Atoi(optstate->value); break;		case 'c':  info.multihash = PR_TRUE; break;		case 'd':  testdir = PL_strdup(optstate->value); break;		case 'e':  info.rsapubexp = PORT_Atoi(optstate->value); break;		case 'g':  info.keysize = PORT_Atoi(optstate->value); break;		case 'i':  infile  = PL_strdup(optstate->value); break;		case 'j':  pqgfile = PL_strdup(optstate->value); break;		case 'k':  keyfile = PL_strdup(optstate->value); break;		case 'm':  cryptofn = get_test_mode(optstate->value);		           mode = PL_strdup(optstate->value); 		           break;		case 'o':  outfile = PL_strdup(optstate->value); break;		case 'p':  info.performance = PR_TRUE; 			   info.repetitions = PORT_Atoi(optstate->value); 			   break;		case 'q':  zerobuffer = PR_TRUE; break;		case 'r':  info.rounds = PORT_Atoi(optstate->value); break;		case 's':  sigfile  = PL_strdup(optstate->value); break;		case 't':  sigseedfile = PL_strdup(optstate->value); break;		case 'v':  ivfile  = PL_strdup(optstate->value); break;		case 'w':  info.wordsize = PORT_Atoi(optstate->value); break;		case 'x':  info.useseed = PR_TRUE; break;		case 'y':  info.usesigseed = PR_TRUE; break;		case 'z':  seedfile  = PL_strdup(optstate->value); break;		case '\0': if (optstate->value[0] != '-')					   modesToTest[numModesToTest++] = 						PL_strdup(optstate->value);				   break;		default: break;		}	}	if (dumpfile)		return dump_file(mode, dumpfile);	if (doselftest) {		if (!info.encrypt && !info.decrypt) {			info.encrypt = info.decrypt = PR_TRUE;  /* do both */		}		if (numModesToTest > 0) {			return blapi_selftest(modesToTest, numModesToTest,			                      info.encrypt, info.decrypt);		} else {			return blapi_selftest(NULL, 0, info.encrypt, info.decrypt);		}	}	if (dofips) {		CK_RV foo = pk11_fipsPowerUpSelfTest();		PR_fprintf(PR_STDOUT, "CK_RV: %d.\n", foo);		return 0;	}	if (!info.encrypt && !info.decrypt && !info.hash && 	    !info.sign && !info.verify)		Usage();	if (!cryptofn) {		printmodes(&info);		return -1;	}	if (info.decrypt && !infile)		Usage();	if (info.performance) {		char buf[256];		PRStatus stat;		stat = PR_GetSystemInfo(PR_SI_HOSTNAME, buf, sizeof(buf));		printf("HOST: %s\n", buf);		stat = PR_GetSystemInfo(PR_SI_SYSNAME, buf, sizeof(buf));		printf("SYSTEM: %s\n", buf);		stat = PR_GetSystemInfo(PR_SI_RELEASE, buf, sizeof(buf));		printf("RELEASE: %s\n", buf);		stat = PR_GetSystemInfo(PR_SI_ARCHITECTURE, buf, sizeof(buf));		printf("ARCH: %s\n", buf);	}	RNG_RNGInit();	RNG_SystemInfoForRNG();	if (keyfile) {		/* RSA and DSA keys are always b64 encoded. */		if (b64 || PL_strcmp(mode,"rsa")==0 || PL_strcmp(mode,"dsa")==0)			get_file_data(keyfile, &info.key, PR_TRUE);		else			get_file_data(keyfile, &info.key, b64);	}	if (ivfile)		get_file_data(ivfile, &info.iv, b64);	if (infile)		get_file_data(infile, &info.in, b64);	if (sigfile)		get_file_data(sigfile, &info.out, PR_TRUE);	if (seedfile) {		get_file_data(seedfile, &info.seed, b64);		info.useseed = PR_TRUE;	}	if (sigseedfile) {		get_file_data(sigseedfile, &info.sigseed, b64);		info.usesigseed = PR_TRUE;	}	if (pqgfile)		get_file_data(pqgfile, &info.pqg, PR_TRUE);	if (zerobuffer) {		PRFileDesc *ifile;		info.in.len = info.bufsize;		info.in.data = PORT_ZAlloc(info.in.len);		ifile = PR_Open("tmp.pt", PR_WRONLY|PR_CREATE_FILE, 00660);		rv = btoa_file(&info.in, ifile);		CHECKERROR((rv < 0), __LINE__);		PR_Close(ifile);	}	rv = (*cryptofn)(&info);		CHECKERROR(rv, __LINE__);	if (!sigfile && info.out.len > 0) {		PRFileDesc *ofile;		if (!outfile)			ofile = PR_Open("tmp.out", PR_WRONLY|PR_CREATE_FILE, 00660);		else			ofile = PR_Open(outfile, PR_WRONLY|PR_CREATE_FILE, 00660);		rv = btoa_file(&info.out, ofile);		PR_Close(ofile);		CHECKERROR((rv < 0), __LINE__);	}	RNG_RNGShutdown();	return SECSuccess;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?