blobtest.c   [plain text]


/* Copyright 1998 Apple Computer, Inc.
 *
 * blobtest.c - test key blob functions
 *
 * Revision History
 * ----------------
 *  23 Mar 1998		Doug Mitchell
 *	Created.
 */
 
#include "Crypt.h"
#include "falloc.h"
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "ckutilsPlatform.h"

#define MIN_PASSWD_LENGTH	4
#define MAX_PASSWD_LENGTH	20
#define DEPTH_DEFAULT		FEE_DEPTH_DEFAULT

#undef	BOOL
#undef	YES
#undef	NO
#define BOOL	int
#define YES	1
#define NO	0

static unsigned char *passwdPool;

static unsigned doBlobTest(unsigned minPasswdLen, 
	unsigned maxPasswdLen, 
	BOOL verbose,
	unsigned depth);
static void usage(char **argv);

int main(int argc, char **argv)
{
	BOOL 		seedSpec = NO;		// YES ==> user specified
	unsigned 	loopNum;
	int 		arg;
	char 		*argp;
	
	/*
	 * User-spec'd variables
	 */
	unsigned 	minPasswordLen = MIN_PASSWD_LENGTH;
	unsigned 	maxPasswordLen = MAX_PASSWD_LENGTH;
	int 		seed = 0;
	unsigned 	loops = 1;	
	BOOL		quiet = NO;
	BOOL		verbose = NO;
	unsigned	depth = DEPTH_DEFAULT;
	
	#if	macintosh
	argc = ccommand(&argv);
	#endif
	for(arg=1; arg<argc; arg++) {
		argp = argv[arg];
		switch(argp[0]) {
		    case 'n':
			minPasswordLen = atoi(&argp[2]);
			break;
		    case 'x':
			maxPasswordLen = atoi(&argp[2]);
			break;
		    case 's':
			seed = atoi(&argp[2]);
			seedSpec = YES;
			break;
		    case 'l':
			loops = atoi(&argp[2]);
			break;
		    case 'D':
			depth = atoi(&argp[2]);
			break;
		    case 'q':
		    	quiet = YES;
			break;
		    case 'v':
		    	verbose = YES;
			break;
		    case 'h':
		    default:
			usage(argv);
		}
	}
	if(seedSpec == NO) {
		unsigned long	tim;
		time(&tim);
		seed = (unsigned)tim;
	}
	SRAND(seed);

	passwdPool = fmalloc(maxPasswordLen + 4);
	
	printf("Starting %s: minPasswd %d maxPasswd %d seed %d depth %d\n",
		argv[0],
		minPasswordLen, maxPasswordLen, seed, depth);
	
	for(loopNum=1; ; loopNum++) {
		if(!quiet) {
			printf("..loop %d\n", loopNum);
		}
		if(doBlobTest(minPasswordLen, maxPasswordLen, verbose, 
				depth)) {
			return 1;
		}
		if(loops && (loopNum == loops)) {
			break;
		}
	}
	if(!quiet) {
		printf("%s test complete\n", argv[0]);
	}
	return 0;
}

static void usage(char **argv)
{
	printf("usage: %s [options]\n", argv[0]);
	printf("   Options:\n");
	printf("   l=loops (0=forever)\n");
	printf("   n=minPasswordLen\n");
	printf("   x=maxPasswdLen\n");
	printf("   s=seed\n");
	printf("   D=depth (default=%d)\n", DEPTH_DEFAULT);
	printf("   q(uiet)\n");
	printf("   v(erbose)\n");
	printf("   h(elp)\n");
	exit(1);
}

static unsigned char *genPasswd(unsigned passwdLength) 
{
	unsigned *ip = (unsigned *)passwdPool;
	unsigned intCount = (passwdLength + 3) / 4;
	int i;
	unsigned char *rtn;
	
	for (i=0; i<intCount; i++) {
		*ip++ = RAND();
	}
	rtn = fmalloc(passwdLength);
	bcopy(passwdPool, rtn, passwdLength);
	return rtn;
}

static unsigned doBlobTest(unsigned minPasswdLen, 
	unsigned maxPasswdLen,
	BOOL verbose,
	unsigned depth)
{
	unsigned char 	*myPasswd = NULL;
	unsigned 	myPasswdLen;
	feePubKey 	myPrivate = NULL;
	feePubKey 	myPrivateCopy = NULL;	// from blob
	feePubKey 	myPublic = NULL;	// from blob from myPrivate
	feePubKey 	myPublicCopy = NULL;	// from blob from myPublic
	unsigned	rtn = 0;
	feeReturn	frtn;
	unsigned char 	*privBlob = NULL;
	unsigned	privBlobLen;
	unsigned char 	*pubBlob = NULL;
	unsigned	pubBlobLen;
	
	for(myPasswdLen=minPasswdLen; 
	    myPasswdLen<maxPasswdLen; 
	    myPasswdLen++) {
		
	    	if(verbose) {
		    printf("....myPasswdLen %d\n", myPasswdLen);
		}

		/*
		 * my private password
		 */
		myPasswd = genPasswd(myPasswdLen);
		
		/*
		 * Fully capable Public Key object
		 */
		myPrivate = feePubKeyAlloc();
		frtn = feePubKeyInitFromPrivDataDepth(myPrivate,
			myPasswd,
			myPasswdLen,
			depth,
			1);
		if(frtn) {
			printf("feePubKeyInitFromPrivDataDepth: %s\n",
				feeReturnString(frtn));
			rtn = 1;
			goto out;
		}
		
		/* private blob */
		frtn = feePubKeyCreatePrivBlob(myPrivate,
			&privBlob,
			&privBlobLen);
		if(frtn) {
			printf("feePubKeyCreatePrivBlob: %s\n",
				feeReturnString(frtn));
			rtn = 1;
			goto out;
		}

		/* private key from private blob */
		myPrivateCopy = feePubKeyAlloc();
		frtn = feePubKeyInitFromPrivBlob(myPrivateCopy,
			privBlob,
			privBlobLen);
		if(frtn) {
			printf("feePubKeyInitFromKeyBlob (private): %s\n",
				feeReturnString(frtn));
			rtn = 1;
			goto out;
		}
		if(!feePubKeyIsPrivate(myPrivateCopy)) {
			printf("Unexpected !feePubKeyIsPrivate!\n");
			rtn = 1;
			goto out;
		}

		/* public blob from private key */
		frtn = feePubKeyCreatePubBlob(myPrivate,
			&pubBlob,
			&pubBlobLen);
		if(frtn) {
			printf("feePubKeyCreatePubBlob (1): %s\n",
				feeReturnString(frtn));
			rtn = 1;
			goto out;
		}

		/* public key from public blob */
		myPublic = feePubKeyAlloc();
		frtn = feePubKeyInitFromPubBlob(myPublic,
			pubBlob,
			pubBlobLen);
		if(frtn) {
			printf("feePubKeyInitFromKeyBlob (pub 1): %s\n",
				feeReturnString(frtn));
			rtn = 1;
			goto out;
		}
		if(feePubKeyIsPrivate(myPublic)) {
			printf("Unexpected feePubKeyIsPrivate (1)!\n");
			rtn = 1;
			goto out;
		}
		ffree(pubBlob);
		pubBlob = NULL;
	
		/* public blob from public key */
		frtn = feePubKeyCreatePubBlob(myPublic,
			&pubBlob,
			&pubBlobLen);
		if(frtn) {
			printf("feePubKeyCreatePubBlob (2): %s\n",
				feeReturnString(frtn));
			rtn = 1;
			goto out;
		}

		/* public key from public blob */
		myPublicCopy = feePubKeyAlloc();
		frtn = feePubKeyInitFromPubBlob(myPublicCopy,
			pubBlob,
			pubBlobLen);
		if(frtn) {
			printf("feePubKeyInitFromKeyBlob (pub 2): %s\n",
				feeReturnString(frtn));
			rtn = 1;
			goto out;
		}
		if(feePubKeyIsPrivate(myPublicCopy)) {
			printf("Unexpected feePubKeyIsPrivate (2)!\n");
			rtn = 1;
			goto out;
		}

		/* private blob from pub key - should fail */
		frtn = feePubKeyCreatePrivBlob(myPublic,
			&pubBlob,
			&pubBlobLen);
		if(frtn == FR_Success) {
		    printf("Unexpected feePubKeyCreatePrivBlob success\n");
		    rtn = 1;
		    goto out;
		}
		
		/*
		 * OK, we have four keys; they should all be equal (in
		 * terms of their actual public data).
		 */
		if(!feePubKeyIsEqual(myPrivate, myPrivateCopy)) {
			printf("myPrivate != myPrivateCopy\n");
			rtn = 1;
			goto out;
		}
		if(!feePubKeyIsEqual(myPrivate, myPublic)) {
			printf("myPrivate != myPublic\n");
			rtn = 1;
			goto out;
		}
		if(!feePubKeyIsEqual(myPrivate, myPublicCopy)) {
			printf("myPrivate != myPublicCopy\n");
			rtn = 1;
			goto out;
		}
		if(!feePubKeyIsEqual(myPublic, myPublicCopy)) {
			printf("myPublic != myPublicCopy\n");
			rtn = 1;
			goto out;
		}
	    out:
		if(myPasswd) {
			ffree(myPasswd);
		}
		if(myPrivate) {
			feePubKeyFree(myPrivate);
		}
		if(myPrivateCopy) {
			feePubKeyFree(myPrivateCopy);
		}
		if(myPublic) {
			feePubKeyFree(myPublic);
		}
		if(myPublic) {
			feePubKeyFree(myPublicCopy);
		}
		if(privBlob) {
			ffree(privBlob);
		}
		if(pubBlob) {
			ffree(pubBlob);
		}
		if(rtn) {
			break;
		}
	}
	return rtn;
}