RNGContext                 *rng; SECStatus                   rv; PRFileDesc                 *fileDesc; SECItem                    *publicValue, *keyID; SECKEYPrivateKey           *foundPrivKey;
DoChallengeResponse(char *configdir, SECKEYPrivateKey *privKey,		    SECKEYPublicKey *pubKey){    CMMFPOPODecKeyChallContent *chalContent = NULL;    CMMFPOPODecKeyRespContent  *respContent = NULL;    CERTCertificate            *myCert      = NULL;    CERTGeneralName            *myGenName   = NULL;    PRArenaPool                *poolp       = NULL;    SECItem                     DecKeyChallBits;    long                       *randomNums;    int                         numChallengesFound=0;    int                         numChallengesSet = 1,i;    long                        retrieved;    char                        filePath[PATH_LEN];    RNGContext                 *rng;    SECStatus                   rv;    PRFileDesc                 *fileDesc;    SECItem                    *publicValue, *keyID;    SECKEYPrivateKey           *foundPrivKey;    chalContent = CMMF_CreatePOPODecKeyChallContent();    myCert = CERT_FindCertByNickname(db, personalCert);    if (myCert == NULL) {        printf ("Could not find the certificate for %s\n", personalCert);        return 900;    }    poolp = PORT_NewArena(1024);    if (poolp == NULL) {        printf("Could no allocate a new arena in DoChallengeResponse\n");	return 901;    }    myGenName = CERT_GetCertificateNames(myCert, poolp);    if (myGenName == NULL) {        printf ("Could not get the general names for %s certificate\n", 		personalCert);	return 902;    }    randomNums = PORT_ArenaNewArray(poolp,long, numChallengesSet);    rng = RNG_CreateContext();    RNG_GenerateRandomBytes(rng, randomNums, numChallengesSet*sizeof(long));    for (i=0; i<numChallengesSet; i++) {	rv = CMMF_POPODecKeyChallContentSetNextChallenge(chalContent,							 randomNums[i],							 myGenName,							 pubKey,							 NULL);    }    RNG_DestroyContext(rng, PR_TRUE);    if (rv != SECSuccess) {        printf ("Could not set the challenge in DoChallengeResponse\n");	return 903;    }    PR_snprintf(filePath, PATH_LEN, "%s/POPODecKeyChallContent.der", 		configdir);    fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,		       0666);    if (fileDesc == NULL) {        printf ("Could not open file %s\n", filePath);	return 904;    }    rv = CMMF_EncodePOPODecKeyChallContent(chalContent,WriteItOut, 					   (void*)fileDesc);    PR_Close(fileDesc);    CMMF_DestroyPOPODecKeyChallContent(chalContent);    if (rv != SECSuccess) {        printf ("Could not encode the POPODecKeyChallContent.\n");	return 905;    }    GetBitsFromFile(filePath, &DecKeyChallBits);    chalContent =       CMMF_CreatePOPODecKeyChallContentFromDER      ((const char*)DecKeyChallBits.data, DecKeyChallBits.len);    PORT_Free(DecKeyChallBits.data);    if (chalContent == NULL) {        printf ("Could not create the POPODecKeyChallContent from DER\n");	return 906;    }    numChallengesFound =       CMMF_POPODecKeyChallContentGetNumChallenges(chalContent);    if (numChallengesFound != numChallengesSet) {        printf ("Number of Challenges Found (%d) does not equal the number "		"set (%d)\n", numChallengesFound, numChallengesSet);	return 907;    }    for (i=0; i<numChallengesSet; i++) {        publicValue = CMMF_POPODecKeyChallContentGetPublicValue(chalContent, i);	if (publicValue == NULL) {	  printf("Could not get the public value for challenge at index %d\n",		 i);	  return 908;	}	keyID = PK11_MakeIDFromPubKey(publicValue);	if (keyID == NULL) {	    printf ("Could not make the keyID from the public value\n");	    return 909;	}	foundPrivKey = PK11_FindKeyByKeyID(privKey->pkcs11Slot,keyID, NULL);	if (foundPrivKey == NULL) {	    printf ("Could not find the private key corresponding to the public"		    " value.\n");	    return 910;	}	rv = CMMF_POPODecKeyChallContDecryptChallenge(chalContent, i, 						      foundPrivKey);	if (rv != SECSuccess) {	    printf ("Could not decrypt the challenge at index %d\n", i);	    return 911;	}	rv = CMMF_POPODecKeyChallContentGetRandomNumber(chalContent, i, 							&retrieved);	if (rv != SECSuccess) {	    printf ("Could not get the random number from the challenge at "		    "index %d\n", i);	    return 912;	}	if (retrieved != randomNums[i]) {	    printf ("Retrieved the number (%d), expected (%d)\n", retrieved,		    randomNums[i]);	    return 913;	}    }    CMMF_DestroyPOPODecKeyChallContent(chalContent);    PR_snprintf(filePath, PATH_LEN, "%s/POPODecKeyRespContent.der", 		configdir);    fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,		       0666);    if (fileDesc == NULL) {        printf ("Could not open file %s\n", filePath);	return 914;    }    rv = CMMF_EncodePOPODecKeyRespContent(randomNums, numChallengesSet,					  WriteItOut, fileDesc);    PR_Close(fileDesc);    if (rv != 0) {        printf ("Could not encode the POPODecKeyRespContent\n");	return 915;    }    GetBitsFromFile(filePath, &DecKeyChallBits);    respContent =      CMMF_CreatePOPODecKeyRespContentFromDER((const char*)DecKeyChallBits.data,					     DecKeyChallBits.len);    if (respContent == NULL) {        printf ("Could not decode the contents of the file %s\n", filePath);	return 916;    }    numChallengesFound =          CMMF_POPODecKeyRespContentGetNumResponses(respContent);    if (numChallengesFound != numChallengesSet) {        printf ("Number of responses found (%d) does not match the number "		"of challenges set (%d)\n",		numChallengesFound, numChallengesSet);	return 917;    }    for (i=0; i<numChallengesSet; i++) {        rv = CMMF_POPODecKeyRespContentGetResponse(respContent, i, &retrieved);	if (rv != SECSuccess) {	    printf ("Could not retrieve the response at index %d\n", i);	    return 918;	}	if (retrieved != randomNums[i]) {	    printf ("Retrieved the number (%ld), expected (%ld)\n", retrieved,		    randomNums[i]);	    return 919;	}							      }    CMMF_DestroyPOPODecKeyRespContent(respContent);    return 0;}