rv = CERT_OpenVolatileCertDB(&certhandle); if (rv != SECSuccess) {
NSS_NoDB_Init(NULL); certhandle = CERT_GetDefaultCertDB(); if (certhandle == NULL) {
main(int argc, char **argv){	char *progname = *argv++;	char *commonName = NULL;	char *caname = NULL;	char *email = NULL;	char *outname = NULL;	char *cp;	int arg_count = 0;	Cert caCert;        SECItem userCert;	int cirv,i;	int cards, start;	unsigned char *subject;	int            subject_len;	int            signature_len = sizeof(signature);	int            newSubject_len, newCertBody_len, len;	int            cname1_len, cname_len, pstring_len;	int            valitity_len = sizeof(valitity);	unsigned char origCert[CERT_SIZE];	unsigned char newSubject[CERT_SIZE];	unsigned char newCertBody[CERT_SIZE];	unsigned char newCert[CERT_SIZE];	unsigned char pstring[CERT_SIZE];	unsigned char cname1[CERT_SIZE];	unsigned char cname[CERT_SIZE];	CERTCertificate *myCACert = NULL;	CERTCertificate *cert;	CERTCertDBHandle certhandle;	SECStatus rv;	SECMODModule *module;	unsigned char serial[16];	SECKEYPublicKey *pubKey;	DSAPrivateKey *keaPrivKey;	DSAPrivateKey *dsaPrivKey;	CI_RANDOM randomVal;	PQGParams *params;	int pca_index = -1;	unsigned char *p,*q,*g;	FORTSkipjackKey Ks;	FORTSkipjackKey Kinit;        FORTSWFile *file;        FORTSignedSWFile *signed_file;        FORTSignedSWFile *signed_file2;	unsigned char random[20];	unsigned char vers;	unsigned char *data;	char *transportPin=NULL;	char *ssoMemPhrase=NULL;	char *userMemPhrase=NULL;	char *ssoPin=NULL;	char *userPin=NULL;	char *pass=NULL;	SECItem *outItem;	int email_len = 0;	int emailAVA_len = 0;       /* put better argument parsing here */    while ((cp = *argv++) != NULL) {	if (*cp == '-') {	    while (*++cp) {		switch (*cp) {		/* verbose mode */		case 'e':		    email = *argv++;		    break;		/* explicitly set the target */		case 'o':		    outname = *argv++;		    break;		case 't':		/* provide password on command line */		    transportPin = *argv++;		    break;		case 'u':		/* provide user password on command line */		    userPin = *argv++;		    break;		case 'U':		/* provide user password on command line */		    userMemPhrase = *argv++;		    break;		case 's':		/* provide user password on command line */		    ssoPin = *argv++;		    break;		case 'S':		/* provide user password on command line */		    ssoMemPhrase = *argv++;		    break;		case 'p':		/* provide card password on command line */		    pass = *argv++;		    break;		case 'd':		    transportPin="test1234567890";		    ssoMemPhrase="sso1234567890";		    userMemPhrase="user1234567890";		    ssoPin="9999";		    userPin="0000";		    break;		default:		    usage(progname);		    break;		}	    }	} else switch (arg_count++) {	    case 0:		commonName = cp;		break;	    case 1:		caname = cp;		break;	    default:		usage(progname);	}     }    if (outname == NULL) outname = "swfort.sfi";    if (caname == NULL) usage(progname);	caCert.card = -1;	memset(newCert,0,CERT_SIZE);	if (commonName == NULL) usage(progname);		cirv = CI_Initialize(&cards);        start = 0;	for (i=0; i < cards; i++) {	    cirv = InitCard(i+1,pass);	    if (cirv == CI_OK) {	      if (FoundCert(i+1,caname,&caCert)) {		break;	      }	    }	}	   	if (caCert.card == -1) {	   fprintf(stderr,	"WARNING: Couldn't find Signing CA...new cert will not be signed\n");	}	/*	 * initialize enough security to deal with certificates.	 */	rv = CERT_OpenVolatileCertDB(&certhandle);	if (rv != SECSuccess) {	    Terminate("Couldn't build temparary Cert Database", 						1, -1, caCert.card);	    exit(1);	}	CERT_SetDefaultCertDB(&certhandle);	RNG_RNGInit();	CI_GenerateRandom(random);	RNG_RandomUpdate(random,sizeof(random));	CI_GenerateRandom(random);	RNG_RandomUpdate(random,sizeof(random));	PK11_InitSlotLists();	module = SECMOD_NewInternal();	if (module == NULL) {	    Terminate("Couldn't initialize security", 1, -1, caCert.card);	    exit(1);	}	rv = SECMOD_LoadModule(module);	if (rv != SECSuccess) {	    Terminate("Couldn't initialize security", 2, -1, caCert.card);	    exit(1);	}    if (transportPin == NULL) transportPin = getPassPhrase();    if (ssoMemPhrase == NULL) ssoMemPhrase = getPassPhrase();    if (userMemPhrase == NULL) userMemPhrase = getPassPhrase();    if (ssoPin == NULL) ssoPin = getPinPhrase();    if (userPin == NULL) userPin = getPinPhrase();	/* now dump the certs into the temparary data base */	for (i=0; i < caCert.count; i++) {	    int trusted = 0;    	    SECItem derCert;	    cirv = CI_Select(caCert.card);	    if (cirv != CI_OK) {		Terminate("Couldn't select on CA card",cirv, 					-1, caCert.card);	    }	    cirv = CI_GetCertificate(caCert.valid[i].index,origCert);            if (cirv != CI_OK) {		continue;	    }	    derCert.data = origCert;	    derCert.len = Cert_length(origCert, sizeof(origCert));	    cert = CERT_NewTempCertificate(&certhandle,&derCert, NULL, 							PR_FALSE, PR_TRUE);	    caCert.valid[i].cert = cert;	    if (cert == NULL) continue;            if (caCert.valid[i].index == caCert.index) myCACert=cert;	    if (caCert.valid[i].index == atoi((char *)&caCert.label[4]))				 pca_index = i;	}	if (myCACert == NULL) {	   Terminate("Couldn't find CA's Certificate", 1, -1, caCert.card);	   exit(1);	}	        /*	 * OK now build the user cert.	 */	/* first get the serial number and KMID */        cirv = CI_GenerateRandom(randomVal);	memcpy(&header[2],randomVal,sizeof(serial));	memcpy(serial,randomVal,sizeof(serial));	memcpy(&key[KEY_START+KMID_OFFSET],randomVal+sizeof(serial),7);							 /* KMID */	/* now generate the keys */	pubKey = CERT_ExtractPublicKey(myCACert);	if (pubKey == NULL) {	   Terminate("Couldn't extract CA's public key", 						1, -1, caCert.card);	   exit(1);	}	switch (pubKey->keyType) {	case fortezzaKey:	    params = &pubKey->u.fortezza.params;	    break;	case dsaKey:	    params = &pubKey->u.dsa.params;	    break;	default:	   Terminate("Certificate is not a fortezza or DSA Cert",					1, -1, caCert.card);	   exit(1);	}	rv = DSA_NewKey(params,&keaPrivKey);	if (rv != SECSuccess) {	   Terminate("Couldn't Generate KEA key", 					PORT_GetError(), -1, caCert.card);	   exit(1);	}	rv = DSA_NewKey(params,&dsaPrivKey);	if (rv != SECSuccess) {	   Terminate("Couldn't Generate DSA key", 					PORT_GetError(), -1, caCert.card);	   exit(1);	}	if (keaPrivKey->publicValue.len == 129) 					keaPrivKey->publicValue.data++;	if (dsaPrivKey->publicValue.len == 129) 					dsaPrivKey->publicValue.data++;	if (keaPrivKey->privateValue.len == 21) 					keaPrivKey->privateValue.data++;	if (dsaPrivKey->privateValue.len == 21) 					dsaPrivKey->privateValue.data++;	/* save the parameters */	p = params->prime.data;	if (params->prime.len == 129) p++;	q = params->subPrime.data;	if (params->subPrime.len == 21) q++;	g = params->base.data;	if (params->base.len == 129) g++;	memcpy(&key[KEY_START+KEA_OFFSET],			keaPrivKey->publicValue.data,			keaPrivKey->publicValue.len);	memcpy(&key[KEY_START+DSA_OFFSET],			dsaPrivKey->publicValue.data,			dsaPrivKey->publicValue.len);	/* build the der subject */	subject = data_start(myCACert->derSubject.data,myCACert->derSubject.len,		&subject_len);	/* build the new Common name AVA */	len = DER_Sequence(pstring,strlen(commonName));	memcpy(pstring+len,commonName,strlen(commonName));					 len += strlen(commonName);	pstring_len = len;	pstring[0] = 0x13;	len = DER_Sequence(cname1,sizeof(cnam_oid)+pstring_len);	memcpy(cname1+len,cnam_oid,sizeof(cnam_oid)); len += sizeof(cnam_oid);	memcpy(cname1+len,pstring,pstring_len); len += pstring_len;	cname1_len = len;	len = DER_Sequence(cname, cname1_len);	memcpy(cname+len,cname1,cname1_len); len += cname1_len;	cname_len = len;	cname[0] = 0x31; /* make it a set rather than a sequence */	if (email) {	    email_len = strlen(email);	    emailAVA_len = EMAIL_DATA_START + email_len;	}	/* now assemble it */	len = DER_Sequence(newSubject,subject_len + sizeof(software_ou) +				cname_len + emailAVA_len);	memcpy(newSubject+len,subject,subject_len);	for (i=0; i < subject_len; i++) {	   if (memcmp(newSubject+len+i,cnam_oid,sizeof(cnam_oid)) == 0) {		newSubject[i+len+4] = 0x0b; /* change CN to OU */		break;	   }	}	len += subject_len;	memcpy(newSubject+len,software_ou,sizeof(software_ou)); 						len += sizeof(software_ou);	memcpy(newSubject+len,cname,cname_len); len += cname_len;	newSubject_len = len;	/*	 * build the email AVA	 */	if (email) {	    memcpy(&emailAVA[EMAIL_DATA_START],email,email_len);	    for (i=0; i < offsetCount; i++) {		emailAVA[emailOffset[i]] += email_len;	    }	    memcpy(newSubject+len,emailAVA,emailAVA_len);	    newSubject_len += emailAVA_len;	}	/*	 * Assemble the Cert	 */	len = DER_Sequence(newCertBody,sizeof(header)+newSubject_len+	   valitity_len+myCACert->derSubject.len+sizeof(key));	memcpy(newCertBody+len,header,sizeof(header));len += sizeof(header);	memcpy(newCertBody+len,myCACert->derSubject.data,		myCACert->derSubject.len);len += myCACert->derSubject.len;	memcpy(newCertBody+len,valitity,valitity_len);len += valitity_len;	memcpy(newCertBody+len,newSubject,newSubject_len);						len += newSubject_len;	memcpy(newCertBody+len,key,sizeof(key));len += sizeof(key);	newCertBody_len = len;	/*	 * generate the hash	 */	cirv = CI_InitializeHash();	if (cirv == CI_OK) {	    int hash_left = newCertBody_len & 63;	    int hash_len = newCertBody_len - hash_left;	    cirv = CI_Hash(hash_len,newCertBody);	    if (cirv == CI_OK) {		cirv = CI_GetHash(hash_left,newCertBody+hash_len,hash);	    }	}	/*	 * now sign the hash	 */	if ((cirv == CI_OK) && (caCert.card != -1)) {	    cirv = CI_Select(caCert.card);	    if (cirv == CI_OK) {		cirv = CI_SetPersonality(caCert.index);		if (cirv == CI_OK) {		    cirv = CI_Sign(hash,sig);		}	    }	} else cirv = -1;	if (cirv != CI_OK) {	   memcpy(sig,hash,sizeof(hash));	}	/*	 * load in new signature	 */	{	    int sig_len;	    unsigned char *sig_start = 			GetSignature(signature,signature_len,&sig_len);	    memcpy(sig_start,sig,sizeof(sig));	}	/*	 * now do the final wrap	 */	len = DER_Sequence(newCert,newCertBody_len+signature_len);	memcpy(newCert+len,newCertBody,newCertBody_len); len += newCertBody_len;	memcpy(newCert+len, signature, signature_len); len +=signature_len;	userCert.data = newCert;	userCert.len = len;	/* OK, we now have our cert, let's go build our software file */	signed_file = PORT_ZNew(FORTSignedSWFile);	file = &signed_file->file;	signed_file->signatureWrap.signature.data  = PORT_ZAlloc(40);	signed_file->signatureWrap.signature.len  = 40;	signed_file->signatureWrap.signatureAlgorithm.algorithm.data  =                                       fortezza_oid;	signed_file->signatureWrap.signatureAlgorithm.algorithm.len = 					sizeof(fortezza_oid);        vers = 1;	fill_in(&file->version,&vers,1);	file->derIssuer.data = myCACert->derSubject.data;	file->derIssuer.len = myCACert->derSubject.len;	file->serialID.data = serial;	file->serialID.len =sizeof(serial);	/* generate out Ks value */	fort_GenerateRandom(Ks,sizeof(Ks));	makeProtectedPhrase(file,&file->initMemPhrase,Kinit,NULL,transportPin);	makeProtectedPhrase(file,&file->ssoMemPhrase,Ks,Kinit,ssoMemPhrase);	makeProtectedPhrase(file,&file->ssoPinPhrase,Ks,Kinit,ssoPin);	makeProtectedPhrase(file,&file->userMemPhrase,Ks,Kinit,userMemPhrase);	makeProtectedPhrase(file,&file->userPinPhrase,Ks,Kinit,userPin);	file->wrappedRandomSeed.data = PORT_ZAlloc(12);	file->wrappedRandomSeed.len = 12;        cirv = fort_GenerateRandom(file->wrappedRandomSeed.data,10);	if (cirv != CI_OK) {	   Terminate("Couldn't get Random Seed", 					cirv, -1, caCert.card);	}	fort_skipjackWrap(Ks,12,file->wrappedRandomSeed.data,                                file->wrappedRandomSeed.data);	file->slotEntries = PORT_ZAlloc(sizeof(fortSlotEntry *)*5);	/* paa */	file->slotEntries[0] = PORT_ZNew(fortSlotEntry);	makeCertSlot(file->slotEntries[0],0,caCert.valid[0].label,				&caCert.valid[0].cert->derCert,						Ks,NULL,NULL,NULL,0,p,q,g);	/* pca */	file->slotEntries[1] = PORT_ZNew(fortSlotEntry);	makeCertSlot(file->slotEntries[1],1,caCert.valid[pca_index].label,				&caCert.valid[pca_index].cert->derCert,						Ks,NULL,NULL,NULL,0,p,q,g);	/* ca */	file->slotEntries[2] = PORT_ZNew(fortSlotEntry);	/* make sure the caCert lable points to our new pca slot location */	caCert.label[4] = '0';	caCert.label[5] = '0';	caCert.label[6] = '0';	caCert.label[7] = '1';	makeCertSlot(file->slotEntries[2],2,caCert.label,&myCACert->derCert,						Ks,NULL,NULL,NULL,0,p,q,g);	/* user */	file->slotEntries[3] = PORT_ZNew(fortSlotEntry);	strncpy(&userLabel[8],commonName,sizeof(CI_PERSON)-8);	makeCertSlot(file->slotEntries[3],3,userLabel,&userCert,Ks,		keaPrivKey->privateValue.data,		dsaPrivKey->privateValue.data,		key, sizeof(key), p, q, g);	file->slotEntries[4] = 0;	/* encode the file so we can sign it */	outItem = FORT_PutSWFile(signed_file);	/* get the der encoded data to sign */	signed_file2 = FORT_GetSWFile(outItem);	/* now sign it */	len = signed_file2->signatureWrap.data.len;	data = signed_file2->signatureWrap.data.data;	/*	 * generate the hash	 */	cirv = CI_InitializeHash();	if (cirv == CI_OK) {	    int hash_left = len & 63;	    int hash_len = len - hash_left;	    cirv = CI_Hash(hash_len,data);	    if (cirv == CI_OK) {		cirv = CI_GetHash(hash_left,data+hash_len,hash);	    }	}	/*	 * now sign the hash	 */	if ((cirv == CI_OK) && (caCert.card != -1)) {	    cirv = CI_Select(caCert.card);	    if (cirv == CI_OK) {		cirv = CI_SetPersonality(caCert.index);		if (cirv == CI_OK) {		    cirv = CI_Sign(hash,sig);		}	    }	} else cirv = -1;	if (cirv != CI_OK) {	   memcpy(sig,hash,sizeof(hash));	}	memcpy( signed_file->signatureWrap.signature.data,sig,sizeof(sig));	signed_file->signatureWrap.signature.len = sizeof(sig)*8; 	/* encode it for the last time */	outItem = FORT_PutSWFile(signed_file);	/*	 * write it out to the .sfi file	 */	{	    int fd = open(outname,O_WRONLY|O_CREAT|O_BINARY,0777);	    write(fd,outItem->data,outItem->len);	    close(fd);	}	CI_Close(CI_POWER_DOWN_FLAG,caCert.card);	CI_Terminate();	printf("Wrote %s to file %s.\n",commonName,outname);	printf("Initialization Memphrase: %s\n",transportPin);	printf("SSO Memphrase: %s\n",ssoMemPhrase);	printf("User Memphrase: %s\n",userMemPhrase);	printf("SSO pin: %s\n",ssoPin);	printf("User pin: %s\n",userPin);	return 0;}