testcrmf.c

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

C
1,528
字号
    caPrivKey = PK11_FindKeyByAnyCert(caCert, NULL);    if (CMMF_KeyRecRepContentGetPKIStatusInfoStatus(keyRecRep) != 	                                                      cmmfGranted) {        PORT_Free(ciphertext);	PK11_FreeSlot(slot);	CMMF_DestroyKeyRecRepContent(keyRecRep);	printf ("A bad status came back with the "		"KeyRecRepContent structure\n");	return 510;    }#define NICKNAME "Key Recovery Test Key"    nickname.data = (unsigned char*)NICKNAME;    nickname.len  = PORT_Strlen(NICKNAME);    certKeyPair = CMMF_KeyRecRepContentGetCertKeyAtIndex(keyRecRep, 0);    CMMF_DestroyKeyRecRepContent(keyRecRep);    rv = CMMF_CertifiedKeyPairUnwrapPrivKey(certKeyPair,					    caPrivKey,					    &nickname,					    PK11_GetInternalKeySlot(),					    db,					    &unwrappedPrivKey, NULL);    CMMF_DestroyCertifiedKeyPair(certKeyPair);    if (rv != SECSuccess) {        printf ("Unwrapping the private key failed.\n");	return 511;    }    /*Now let's try to decrypt the ciphertext with the "recovered" key*/    PK11_EnterSlotMonitor(slot);    crv =       PK11_GETTAB(slot)->C_DecryptInit(unwrappedPrivKey->pkcs11Slot->session,				       &mech,				       unwrappedPrivKey->pkcs11ID);    if (crv != CKR_OK) {        PK11_ExitSlotMonitor(slot);	PORT_Free(ciphertext);	PK11_FreeSlot(slot);	printf ("Decrypting with the recovered key failed.\n");	return 513;    }    bytes_decrypted = KNOWN_MESSAGE_LENGTH;    crv = PK11_GETTAB(slot)->C_Decrypt(unwrappedPrivKey->pkcs11Slot->session,				       ciphertext, 				       bytes_encrypted, plaintext,				       &bytes_decrypted);    SECKEY_DestroyPrivateKey(unwrappedPrivKey);    PK11_ExitSlotMonitor(slot);    PORT_Free(ciphertext);    if (crv != CKR_OK) {        PK11_FreeSlot(slot);	printf ("Decrypting the ciphertext with recovered key failed.\n");	return 514;    }    if ((bytes_decrypted != KNOWN_MESSAGE_LENGTH) || 	(PORT_Memcmp(plaintext, known_message, KNOWN_MESSAGE_LENGTH) != 0)) {        PK11_FreeSlot(slot);	printf ("The recovered plaintext does not equal the known message:\n"		"\tKnown message:       %s\n"		"\tRecovered plaintext: %s\n", known_message, plaintext);	return 515;    }    return 0;}intDoChallengeResponse(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;}char *certdb_name_cb(void *arg, int dbVersion){    char *configdir = (char *)arg;    char *dbver;    switch (dbVersion) {    case 7:       dbver = "7";       break;    case 6:       dbver = "6";       break;    case 5:        dbver = "5";    case 4:    default:        dbver = "";	break;    }    return PR_smprintf("%s/cert%s.db", configdir, dbver);}SECStatusOpenCertDB(char *configdir){    CERTCertDBHandle *certdb;    SECStatus         status = SECFailure;    certdb = PORT_ZNew(CERTCertDBHandle);    if (certdb == NULL) {        goto loser;    }    status = CERT_OpenCertDB(certdb, PR_TRUE, certdb_name_cb, configdir);    if (status == SECSuccess) {        CERT_SetDefaultCertDB(certdb);	db = certdb;    } else {        PORT_Free(certdb);    } loser:    return status;}char *keydb_name_cb(void *arg, int dbVersion){    char *configdir = (char*) arg;    char *dbver;    switch(dbVersion){    case 3:        dbver = "3";	break;    case 2:    default:        dbver = "";	break;    }    return PR_smprintf("%s/key%s.db", configdir, dbver);}SECStatusOpenKeyDB(char *configdir){    SECKEYKeyDBHandle *keydb;    keydb = SECKEY_OpenKeyDB(PR_FALSE, keydb_name_cb, configdir);    if (keydb == NULL) {        return SECFailure;    }    SECKEY_SetDefaultKeyDB(keydb);    return SECSuccess;}SECStatusOpenSecModDB(char *configdir){    char *secmodname = PR_smprintf("%d/secmod.db", configdir);    if (secmodname == NULL) {        return SECFailure;    }    SECMOD_init(secmodname);    return SECSuccess;}voidCloseHCL(void){    CERTCertDBHandle  *certHandle;    SECKEYKeyDBHandle *keyHandle;        certHandle = CERT_GetDefaultCertDB();    if (certHandle) {        CERT_ClosePermCertDB(certHandle);    }    keyHandle = SECKEY_GetDefaultKeyDB();    if (keyHandle) {        SECKEY_CloseKeyDB(keyHandle);    }}SECStatusInitHCL(char *configdir){    SECStatus status;    SECStatus rv = SECFailure;    RNG_RNGInit();    RNG_SystemInfoForRNG();    status = OpenCertDB(configdir);    if (status != SECSuccess) {        goto loser;    }        status = OpenKeyDB(configdir);    if (status != SECSuccess) {        goto loser;    }        status = OpenSecModDB(configdir);    if (status != SECSuccess) {       goto loser;    }        rv = SECSuccess; loser:    if (rv != SECSuccess) {        CloseHCL();    }    return rv;}voidUsage (void){    printf ("Usage:\n"	    "\tcrmftest -d [Database Directory] -p [Personal Cert]\n"	    "\t         -e [Encrypter] -s [CA Certificate]\n\n"	    "Database Directory\n"	    "\tThis is the directory where the key3.db, cert7.db, and\n"	    "\tsecmod.db files are located.  This is also the directory\n"	    "\twhere the program will place CRMF/CMMF der files\n"	    "Personal Cert\n"	    "\tThis is the certificate that already exists in the cert\n"	    "\tdatabase to use while encoding the response.  The private\n"	    "\tkey associated with the certificate must also exist in the\n"	    "\tkey database.\n"	    "Encrypter\n"	    "\tThis is the certificate to use when encrypting the the \n"	    "\tkey recovery response.  The private key for this cert\n"	    "\tmust also be present in the key database.\n"	    "CA Certificate\n"	    "\tThis is the nickname of the certificate to use as the\n"	    "\tCA when doing all of the encoding.\n");}intmain(int argc, char **argv) {    CRMFCertRequest *certReq, *certReq2;    CRMFCertReqMsg *certReqMsg;    CRMFCertReqMsg *secondMsg;    char *configdir;    int irv;    SECStatus rv;    SECKEYPrivateKey *privKey;    SECKEYPublicKey  *pubKey;    int o;    PRBool hclInit = PR_FALSE, pArg = PR_FALSE, eArg = PR_FALSE,            sArg = PR_FALSE;    printf ("\ncrmftest v1.0\n");    while (-1 != (o = getopt(argc, argv, "d:p:e:s:"))) {        switch(o) {	case 'd':	    configdir = PORT_Strdup(optarg);	    rv = InitHCL(configdir);	    if (rv != SECSuccess) {	        printf ("InitHCL failed\n");		return 101;	    }	      	    hclInit = PR_TRUE;	    break;	case 'p':	    personalCert = PORT_Strdup(optarg);	    if (personalCert == NULL) {	        return 603;	    }	    pArg = PR_TRUE;	    break;	case 'e':	    recoveryEncrypter = PORT_Strdup(optarg);	    if (recoveryEncrypter == NULL) {	        return 602;	    }	    eArg = PR_TRUE;	    break;	case 's':	    caCertName = PORT_Strdup(optarg);	    if (caCertName == NULL) {	        return 604;	    }	    sArg = PR_TRUE;	    break;	default:	  Usage();	  return 601;	}    }    if (!hclInit || !pArg || !eArg || !sArg) {        Usage();	return 600;    }    InitPKCS11();        irv = CreateCertRequest(&certReq, &privKey, &pubKey);    if (irv != 0 || certReq == NULL) {        goto loser;    }    certReqMsg = CRMF_CreateCertReqMsg();    secondMsg  = CRMF_CreateCertReqMsg();    CRMF_CertReqMsgSetCertRequest(certReqMsg, certReq);    CRMF_CertReqMsgSetCertRequest(secondMsg,  certReq);    irv = AddProofOfPossession(certReqMsg, privKey, pubKey, crmfSignature);    irv = AddProofOfPossession(secondMsg, privKey, pubKey, crmfKeyAgreement);    irv = Encode (certReqMsg, secondMsg, configdir);    if (irv != 0) {        goto loser;    }        rv = CRMF_DestroyCertRequest (certReq);    if (rv != SECSuccess) {        printf ("Error when destroy certificate request.\n");	irv = 100;	goto loser;    }    rv = CRMF_DestroyCertReqMsg(certReqMsg);    CRMF_DestroyCertReqMsg(secondMsg);    irv = Decode (configdir);    if (irv != 0) {        printf("Error while decoding\n");	goto loser;    }    if ((irv = DoCMMFStuff(configdir)) != 0) {        printf ("CMMF tests failed.\n");	goto loser;    }    if ((irv = DoKeyRecovery(configdir, privKey)) != 0) {        printf ("Error doing key recovery\n");	goto loser;    }    if ((irv = DoChallengeResponse(configdir, privKey, pubKey)) != 0) {        printf ("Error doing challenge-response\n");	goto loser;    }    printf ("Exiting successfully!!!\n\n");    irv = 0; loser:    CloseHCL();    PORT_Free(configdir);    return irv;}

⌨️ 快捷键说明

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