testcrmf.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:43k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. #include "crmf.h"
  34. #include "secrng.h"
  35. #include "secpkcs5.h"
  36. #include "pk11func.h"
  37. #include "pkcs11.h"
  38. #include "secmod.h"
  39. #include "secmodi.h"
  40. #include "key.h"
  41. #include "prio.h"
  42. #include "pqggen.h"
  43. #include "cmmf.h"
  44. #include "seccomon.h"
  45. #include "secmod.h"
  46. #include "prlock.h"
  47. #include "secmodi.h"
  48. #include "pkcs11.h"
  49. #include "pk11func.h"
  50. #include "secitem.h"
  51. #include "key.h"
  52. #include "rsa.h"
  53. #include "secpkcs5.h"
  54. #include "secasn1.h"
  55. #include "sechash.h"
  56. #include "cert.h"
  57. #include "secerr.h"
  58. #include <stdio.h>
  59. #include "prprf.h"
  60. #if !defined(XP_UNIX) && !defined(LINUX)
  61. extern int getopt(int, char **, char*);
  62. extern char *optarg;
  63. #endif
  64. #define MAX_KEY_LEN 512
  65. int64 notBefore;
  66. char *personalCert      = NULL;
  67. char *recoveryEncrypter = NULL;
  68. char *caCertName        = NULL;
  69. CERTCertDBHandle *db;
  70. SECKEYKeyDBHandle *keydb;
  71. void 
  72. debug_test(SECItem *src, char *filePath)
  73. {
  74.     PRFileDesc *fileDesc;
  75.     fileDesc = PR_Open (filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 
  76. 0666);
  77.     if (fileDesc == NULL) {
  78.         printf ("Could not cretae file %s.n", filePath);
  79. return;
  80.     }
  81.     PR_Write(fileDesc, src->data, src->len);
  82.     
  83. }
  84. SECStatus
  85. get_serial_number(long *dest)
  86. {
  87.    RNGContext *rng;
  88.    SECStatus   rv;
  89.    if (dest == NULL) {
  90.        return SECFailure;
  91.    }
  92.    rng = RNG_CreateContext();
  93.    if (rng == NULL) {
  94.        *dest = 0;
  95.        return SECFailure;
  96.    }
  97.    rv = RNG_GenerateRandomBytes(rng, (void*)dest, sizeof(long));
  98.    RNG_DestroyContext(rng, PR_TRUE);
  99.     return SECSuccess;
  100. }
  101. char *
  102. promptForPassword (PK11SlotInfo *slot, PRBool retry, void *cx)
  103. {
  104.     char passWord[80];
  105.     char *retPass = NULL;
  106.     
  107.     if (retry) {
  108.         printf ("Incorrect password.  Please re-enter the password.n");
  109.     } 
  110.     printf ("WARNING: Password will be echoed to the screen.n");
  111.     printf ("Please enter the password for slot "%s":", 
  112.     PK11_GetTokenName(slot));
  113.     scanf ("%s", passWord);
  114.     retPass = PORT_Strdup(passWord);
  115.     return retPass;
  116. }
  117. PK11RSAGenParams *
  118. GetRSAParams(void) 
  119. {
  120.     PK11RSAGenParams *rsaParams;
  121.     rsaParams = PORT_ZNew(PK11RSAGenParams);
  122.     if (rsaParams == NULL)
  123.       return NULL;
  124.     rsaParams->keySizeInBits = MAX_KEY_LEN;
  125.     rsaParams->pe = 0x1001;
  126.     
  127.     return rsaParams;
  128.     
  129. }
  130. SECStatus
  131. SetSlotPassword(PK11SlotInfo *slot)
  132. {
  133.     char userPin[80];
  134.     printf ("Initialization of PIN's for your Database.n");
  135.     printf ("------------------------------------------n");
  136.     printf ("Please enter the PIN's for your Database.n");
  137.     printf ("Warning: ALL PIN'S WILL BE ECHOED TO SCREEN!!!n");
  138.     printf ("Now enter the PIN for the user: ");
  139.     scanf  ("%s", userPin);
  140.     return PK11_InitPin (slot, NULL, userPin);
  141. }
  142. PQGParams*
  143. GetDSAParams(void)
  144. {
  145.     PQGParams *params = NULL;
  146.     PQGVerify *vfy = NULL;
  147.     SECStatus  rv;
  148.     rv = PQG_ParamGen(0, &params, &vfy);
  149.     if (rv != SECSuccess) {
  150.         return NULL;
  151.     }
  152.     PQG_DestroyVerify(vfy);
  153.     return params;
  154. }
  155. CERTSubjectPublicKeyInfo *
  156. GetSubjectPubKeyInfo(SECKEYPrivateKey **destPrivKey, 
  157.      SECKEYPublicKey  **destPubKey) {
  158.     CERTSubjectPublicKeyInfo *spki       = NULL;
  159.     SECKEYPrivateKey         *privKey    = NULL;
  160.     SECKEYPublicKey          *pubKey     = NULL;
  161.     PK11SlotInfo             *keySlot    = NULL;
  162.     PK11RSAGenParams         *rsaParams  = NULL;
  163.     PQGParams                *dsaParams  = NULL;
  164.     
  165.     keySlot = PK11_GetInternalKeySlot();
  166.     PK11_Authenticate(keySlot, PR_FALSE, NULL);
  167.     PK11_Authenticate(PK11_GetInternalSlot(), PR_FALSE, NULL);
  168.     rsaParams  = GetRSAParams();
  169.     privKey = PK11_GenerateKeyPair(keySlot, CKM_RSA_PKCS_KEY_PAIR_GEN,
  170.    (void*)rsaParams, &pubKey, PR_FALSE,
  171.    PR_FALSE, NULL);
  172. /*    dsaParams = GetDSAParams();
  173.     if (dsaParams == NULL) {
  174.         return NULL;
  175.     }
  176.     privKey = PK11_GenerateKeyPair(keySlot, CKM_DSA_KEY_PAIR_GEN,
  177.    (void*)dsaParams, &pubKey, PR_FALSE,
  178.    PR_FALSE, NULL);*/
  179.     if (privKey == NULL || pubKey == NULL) {
  180.         if (pubKey) {
  181.     SECKEY_DestroyPublicKey(pubKey);
  182. }
  183. if (privKey) {
  184.     SECKEY_DestroyPrivateKey(privKey);
  185. }
  186. return NULL;
  187.     }
  188.     spki = SECKEY_CreateSubjectPublicKeyInfo(pubKey);
  189.     *destPrivKey = privKey;
  190.     *destPubKey  = pubKey;
  191.     return spki;
  192. }
  193. SECStatus
  194. InitPKCS11(void)
  195. {
  196.     PK11SlotInfo *cryptoSlot, *keySlot;
  197.     PK11_SetPasswordFunc(promptForPassword);
  198.     cryptoSlot = PK11_GetInternalSlot();
  199.     keySlot    = PK11_GetInternalKeySlot();
  200.     
  201.     if (PK11_NeedUserInit(cryptoSlot) && PK11_NeedLogin(cryptoSlot)) {
  202.         if (SetSlotPassword (cryptoSlot) != SECSuccess) {
  203.     printf ("Initializing the PIN's failed.n");
  204.     return SECFailure;
  205. }
  206.     }
  207.     
  208.     if (PK11_NeedUserInit(keySlot) && PK11_NeedLogin(keySlot)) {
  209.         if (SetSlotPassword (keySlot) != SECSuccess) {
  210.     printf ("Initializing the PIN's failed.n");
  211.     return SECFailure;
  212. }
  213.     }
  214.     PK11_FreeSlot(cryptoSlot);
  215.     PK11_FreeSlot(keySlot);
  216.     return SECSuccess;
  217. }
  218. void 
  219. WriteItOut (void *arg, const char *buf, unsigned long len)
  220. {
  221.     PRFileDesc *fileDesc = (PRFileDesc*)arg;
  222.     PR_Write(fileDesc, (void*)buf, len);
  223. }
  224. SECItem
  225. GetRandomBitString(void)
  226. {
  227. #define NUM_BITS     800
  228. #define BITS_IN_BYTE 8
  229.     SECItem bitString;
  230.     int numBytes = NUM_BITS/BITS_IN_BYTE;
  231.     unsigned char *bits = PORT_ZNewArray(unsigned char, numBytes);
  232.     RNGContext *rng;
  233.     rng = RNG_CreateContext();
  234.     RNG_GenerateRandomBytes(rng, (void*)bits, numBytes);
  235.     RNG_DestroyContext(rng, PR_TRUE);
  236.     bitString.data = bits;
  237.     bitString.len = NUM_BITS;
  238.     bitString.type = siBuffer;
  239.     return bitString;
  240. }
  241. CRMFCertExtCreationInfo*
  242. GetExtensions(void)
  243. {
  244.     CRMFCertExtCreationInfo *extInfo;
  245.     CRMFCertExtension *currExt;
  246.     CRMFCertExtension *extension;
  247.     SECItem data;
  248.     PRBool prFalse = PR_FALSE;
  249.     unsigned char keyUsage[4];
  250.     data.len = 4;
  251.     data.data = keyUsage;
  252.     keyUsage[0] = 0x03;
  253.     keyUsage[1] = 0x02;
  254.     keyUsage[2] = 0x07;
  255.     keyUsage[3] = KU_DIGITAL_SIGNATURE;
  256.     extension = CRMF_CreateCertExtension(SEC_OID_X509_KEY_USAGE,prFalse,
  257.  &data);
  258.     extInfo = PORT_ZNew(CRMFCertExtCreationInfo);
  259.     extInfo->numExtensions = 1;
  260.     extInfo->extensions = PORT_ZNewArray(CRMFCertExtension*, 1);
  261.     extInfo->extensions[0] = extension;
  262.     return extInfo;
  263. }
  264. void
  265. FreeExtInfo(CRMFCertExtCreationInfo *extInfo)
  266. {
  267.     int i;
  268.     
  269.     for (i=0; i<extInfo->numExtensions; i++) {
  270.         CRMF_DestroyCertExtension(extInfo->extensions[i]);
  271.     }
  272.     PORT_Free(extInfo->extensions);
  273.     PORT_Free(extInfo);
  274. }
  275. int
  276. CreateCertRequest (CRMFCertRequest **inCertReq, SECKEYPrivateKey **privKey,
  277.    SECKEYPublicKey **pubKey)
  278. {
  279.     long serialNumber;
  280.     long version = 3;
  281.     char *issuerStr = PORT_Strdup ("CN=Javi's CA Shack, O=Information Systems");
  282.     char *subjectStr = PORT_Strdup ("CN=Javi's CA Shack ID, O=Engineering, "
  283.     "C=US");
  284.     CRMFCertRequest *certReq;
  285.     SECAlgorithmID * algID;
  286.     CERTName *issuer, *subject;
  287.     CRMFValidityCreationInfo validity;
  288.     CERTSubjectPublicKeyInfo *spki;
  289.     SECStatus rv;
  290.     SECOidTag tag, tag2;
  291.     SECItem issuerUID, subjectUID;
  292.     CRMFCertExtCreationInfo *extInfo;
  293.     CRMFEncryptedKey  *encKey;
  294.     CERTCertificate *caCert;
  295.     CRMFPKIArchiveOptions *pkiArchOpt;
  296.   
  297.     *inCertReq = NULL;
  298.     certReq = CRMF_CreateCertRequest(0x0ff02345);
  299.     if (certReq == NULL) {
  300.         printf ("Could not initialize a certificate request.n");
  301. return 1;
  302.     }
  303.     rv = CRMF_CertRequestSetTemplateField (certReq, crmfVersion, (void*)(&version));
  304.     if (rv != SECSuccess) {
  305.         printf("Could not add the version number to the "
  306.        "Certificate Request.n");
  307. CRMF_DestroyCertRequest(certReq);
  308. return 2;
  309.     }
  310.     if (get_serial_number(&serialNumber) != SECSuccess) {
  311.         printf ("Could not generate a serial number for cert request.n");
  312. CRMF_DestroyCertRequest(certReq);
  313. return 3;
  314.     }
  315.     rv = CRMF_CertRequestSetTemplateField (certReq, crmfSerialNumber, 
  316.       (void*)(&serialNumber));
  317.     if (rv != SECSuccess) {
  318.         printf ("Could not add serial number to certificate templaten.");
  319. CRMF_DestroyCertRequest(certReq);
  320. return 4;
  321.     }
  322.     
  323.     issuer = CERT_AsciiToName(issuerStr);
  324.     if (issuer == NULL) {
  325.         printf ("Could not create CERTName structure from %s.n", issuerStr);
  326. CRMF_DestroyCertRequest(certReq);
  327. return 5;
  328.     }
  329.     rv = CRMF_CertRequestSetTemplateField (certReq, crmfIssuer, (void*) issuer);
  330.     PORT_Free(issuerStr);
  331.     CERT_DestroyName(issuer);
  332.     if (rv != SECSuccess) {
  333.         printf ("Could not add issuer to cert templaten");
  334. CRMF_DestroyCertRequest(certReq);
  335. return 6;
  336.     }
  337.     subject = CERT_AsciiToName(subjectStr);
  338.     if (subject == NULL) {
  339.         printf ("Could not create CERTName structure from %s.n", subjectStr);
  340. CRMF_DestroyCertRequest(certReq);
  341. return 7;
  342.     }
  343.     PORT_Free(subjectStr);
  344.     rv = CRMF_CertRequestSetTemplateField (certReq, crmfSubject, (void*)subject);
  345.     if (rv != SECSuccess) {
  346.         printf ("Could not add subject to cert templaten");
  347. CRMF_DestroyCertRequest(certReq);
  348. return 8;
  349.     }
  350.     CERT_DestroyName(subject);
  351.     algID = 
  352.    SEC_PKCS5CreateAlgorithmID (SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC,
  353.        NULL, 1);
  354.     if (algID == NULL) {
  355.         printf ("Couldn't create algorithm IDn");
  356. CRMF_DestroyCertRequest(certReq);
  357. return 9;
  358.     }
  359.     rv = CRMF_CertRequestSetTemplateField(certReq, crmfSigningAlg, (void*)algID);
  360.     SECOID_DestroyAlgorithmID(algID, PR_TRUE);
  361.     if (rv != SECSuccess) {
  362.         printf ("Could not add the signing algorithm to the cert template.n");
  363. CRMF_DestroyCertRequest(certReq);
  364. return 10;
  365.     }
  366.     validity.notBefore = &notBefore;
  367.     validity.notAfter  = NULL;
  368.     notBefore = PR_Now();
  369.     rv = CRMF_CertRequestSetTemplateField(certReq, crmfValidity,(void*)(&validity));
  370.     if (rv != SECSuccess) {
  371.         printf ("Could not add validity to cert templaten");
  372. CRMF_DestroyCertRequest(certReq);
  373. return 11;
  374.     }
  375.     spki = GetSubjectPubKeyInfo(privKey, pubKey);
  376.     if (spki == NULL) {
  377.         printf ("Could not create a Subject Public Key Info to addn");
  378. CRMF_DestroyCertRequest(certReq);
  379. return 12;
  380.     }
  381.     rv = CRMF_CertRequestSetTemplateField(certReq, crmfPublicKey, (void*)spki);
  382.     SECKEY_DestroySubjectPublicKeyInfo(spki);
  383.     if (rv != SECSuccess) {
  384.         printf ("Could not add the public key to the templaten");
  385. CRMF_DestroyCertRequest(certReq);
  386. return 13;
  387.     }
  388.     
  389.     caCert = 
  390.       CERT_FindCertByNickname(CERT_GetDefaultCertDB(), 
  391.       caCertName);
  392.     if (caCert == NULL) {
  393.         printf ("Could not find the certificate for %sn", caCertName);
  394.         CRMF_DestroyCertRequest(certReq);
  395. return 50;
  396.     }
  397.     issuerUID = GetRandomBitString();
  398.     subjectUID = GetRandomBitString();
  399.     CRMF_CertRequestSetTemplateField(certReq,crmfIssuerUID,  (void*)&issuerUID);
  400.     CRMF_CertRequestSetTemplateField(certReq,crmfSubjectUID, (void*)&subjectUID);
  401.     PORT_Free(issuerUID.data);
  402.     PORT_Free(subjectUID.data);
  403.     extInfo = GetExtensions();
  404.     CRMF_CertRequestSetTemplateField(certReq, crmfExtension, (void*)extInfo);
  405.     FreeExtInfo(extInfo);
  406.     encKey = CRMF_CreateEncryptedKeyWithEncryptedValue(*privKey, caCert);
  407.     CERT_DestroyCertificate(caCert);
  408.     if (encKey == NULL) {
  409.         printf ("Could not create Encrypted Key with Encrypted Value.n");
  410. return 14;
  411.     }
  412.     pkiArchOpt = CRMF_CreatePKIArchiveOptions(crmfEncryptedPrivateKey, encKey);
  413.     CRMF_DestroyEncryptedKey(encKey);
  414.     if (pkiArchOpt == NULL) {
  415.         printf ("Could not create PKIArchiveOptions.n");
  416. return 15;
  417.     }
  418.     rv  = CRMF_CertRequestSetPKIArchiveOptions(certReq, pkiArchOpt);
  419.     CRMF_DestroyPKIArchiveOptions(pkiArchOpt);
  420.     if (rv != SECSuccess) {
  421.         printf ("Could not add the PKIArchiveControl to Cert Request.n");
  422. return 16;
  423.     }
  424.     *inCertReq = certReq;
  425.     return 0;
  426. }
  427. int 
  428. Encode (CRMFCertReqMsg *inCertReq, 
  429. CRMFCertReqMsg *secondReq, char *configdir)
  430. {   
  431. #define PATH_LEN  150
  432. #define CRMF_FILE "CertReqMessages.der"
  433.     char filePath[PATH_LEN];
  434.     PRFileDesc *fileDesc;
  435.     SECStatus rv;
  436.     int irv = 0;
  437.     CRMFCertReqMsg *msgArr[3];
  438.     CRMFCertReqMsg *newMsg;
  439.     PR_snprintf(filePath, PATH_LEN, "%s/%s", configdir, CRMF_FILE);
  440.     fileDesc = PR_Open (filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 
  441. 0666);
  442.     if (fileDesc == NULL) {
  443.         printf ("Could not open file %sn", filePath);
  444. irv = 14;
  445. goto finish;
  446.     }
  447. /*    rv = CRMF_EncodeCertReqMsg (inCertReq, WriteItOut, (void*)fileDesc);*/
  448.     msgArr[0] = inCertReq;
  449.     msgArr[1] = secondReq;
  450.     msgArr[2] = NULL;
  451.     rv = CRMF_EncodeCertReqMessages(msgArr, WriteItOut, (void*)fileDesc);
  452.     if (rv != SECSuccess) {
  453.         printf ("An error occurred while encoding.n");
  454. irv = 15;
  455. goto finish;
  456.     }
  457.  finish:
  458.     PR_Close(fileDesc);
  459.     return irv;
  460. }
  461. int
  462. AddProofOfPossession(CRMFCertReqMsg *certReqMsg, SECKEYPrivateKey *privKey,
  463.      SECKEYPublicKey *pubKey, CRMFPOPChoice inPOPChoice)
  464. {
  465.     switch(inPOPChoice){
  466.     case crmfSignature:
  467.       CRMF_CertReqMsgSetSignaturePOP(certReqMsg, privKey, pubKey, NULL, NULL, 
  468.      NULL);
  469.       break;
  470.     case crmfRAVerified:
  471.       CRMF_CertReqMsgSetRAVerifiedPOP(certReqMsg);
  472.       break;
  473.     case crmfKeyEncipherment:
  474.       CRMF_CertReqMsgSetKeyEnciphermentPOP(certReqMsg,
  475.    crmfSubsequentMessage, 
  476.    crmfChallengeResp, NULL);
  477.       break;
  478.     case crmfKeyAgreement:
  479.       {
  480. SECItem pendejo;
  481. unsigned char lame[] = { 0xf0, 0x0f, 0xf0, 0x0f, 0xf0 };
  482. pendejo.data = lame;
  483. pendejo.len  = 5;
  484. CRMF_CertReqMsgSetKeyAgreementPOP(certReqMsg, crmfThisMessage, 
  485.   crmfNoSubseqMess, &pendejo);
  486.       }
  487.       break;
  488.     default:
  489.       return 1;
  490.     }
  491.     return 0;
  492. }
  493. #define BUFF_SIZE  150
  494. int
  495. Decode(char *configdir)
  496. {
  497.     char           filePath[PATH_LEN];
  498.     unsigned char  buffer[BUFF_SIZE];
  499.     char          *asn1Buff;
  500.     PRFileDesc    *fileDesc;
  501.     PRInt32          fileLen = 0;
  502.     PRInt32          bytesRead;
  503.     CRMFCertReqMsg  *certReqMsg;
  504.     CRMFCertRequest *certReq;
  505.     CRMFGetValidity validity= {NULL, NULL};
  506.     CRMFCertReqMessages *certReqMsgs;
  507.     int numMsgs, i;
  508.     long lame;
  509.     PR_snprintf(filePath, PATH_LEN, "%s/%s", configdir, CRMF_FILE);
  510.     fileDesc = PR_Open(filePath, PR_RDONLY, 0644);
  511.     while (1) {
  512.         bytesRead = PR_Read(fileDesc, buffer, BUFF_SIZE);
  513. if (bytesRead <= 0) break;
  514. fileLen += bytesRead;
  515.     }
  516.     if (bytesRead < 0) {
  517.         printf ("Error while getting the length of the file %sn", filePath);
  518. return 200;
  519.     }
  520.     
  521.     PR_Close(fileDesc);
  522.     fileDesc = PR_Open(filePath, PR_RDONLY, 0644);
  523.     asn1Buff = PORT_ZNewArray(char, fileLen);
  524.     bytesRead = PR_Read(fileDesc, asn1Buff, fileLen);
  525.     if (bytesRead != fileLen) {
  526.         printf ("Error while reading in the contents of %sn", filePath);
  527. return 201;
  528.     }
  529.     /*certReqMsg = CRMF_CreateCertReqMsgFromDER(asn1Buff, fileLen);
  530.     if (certReqMsg == NULL) {
  531.         printf ("Error while decoding the CertReqMsgn");
  532. return 202;
  533.     }
  534.     certReq = CRMF_CertReqMsgGetCertRequest(certReqMsg);
  535. */
  536.     certReqMsgs = CRMF_CreateCertReqMessagesFromDER(asn1Buff, fileLen);
  537.     if (certReqMsgs == NULL) {
  538.         printf ("Error decoding CertReqMessages.n");
  539. return 202;
  540.     }
  541.     numMsgs = CRMF_CertReqMessagesGetNumMessages(certReqMsgs);
  542.     if (numMsgs <= 0) {
  543.         printf ("WARNING: The DER contained %d messages.n", numMsgs);
  544.     }
  545.     for (i=0; i < numMsgs; i++) {
  546.         certReqMsg = CRMF_CertReqMessagesGetCertReqMsgAtIndex(certReqMsgs, i);
  547. if (certReqMsg == NULL) {
  548.     printf ("ERROR: Could not access the message at index %d of %sn",
  549.     i, filePath);
  550. }
  551. CRMF_CertReqMsgGetID(certReqMsg, &lame);
  552. certReq = CRMF_CertReqMsgGetCertRequest(certReqMsg);
  553. CRMF_CertRequestGetCertTemplateValidity(certReq, &validity);
  554. CRMF_DestroyGetValidity(&validity);
  555. CRMF_DestroyCertRequest(certReq);
  556. CRMF_DestroyCertReqMsg(certReqMsg);
  557.     }
  558.     CRMF_DestroyCertReqMessages(certReqMsgs);
  559.     PORT_Free(asn1Buff);
  560.     return 0;
  561. }
  562. void
  563. GetBitsFromFile(char *filePath, SECItem *fileBits)
  564. {
  565.     PRFileDesc *fileDesc;
  566.     int         bytesRead, fileLen=0;
  567.     char        buffer[BUFF_SIZE], *asn1Buf;
  568.     fileDesc = PR_Open(filePath, PR_RDONLY, 0644);
  569.     while (1) {
  570.         bytesRead = PR_Read(fileDesc, buffer, BUFF_SIZE);
  571. if (bytesRead <= 0) break;
  572. fileLen += bytesRead;
  573.     }
  574.     if (bytesRead < 0) {
  575.         printf ("Error while getting the length of file %s.n", filePath);
  576. goto loser;
  577.     }
  578.     PR_Close(fileDesc);
  579.     
  580.     fileDesc = PR_Open(filePath, PR_RDONLY, 0644);
  581.     asn1Buf = PORT_ZNewArray(char, fileLen);
  582.     if (asn1Buf == NULL) {
  583.         printf ("Out of memory in function GetBitsFromFilen");
  584.         goto loser;
  585.     }
  586.     bytesRead = PR_Read(fileDesc, asn1Buf, fileLen);
  587.     if (bytesRead != fileLen) {
  588.         printf ("Error while reading the contents of %sn", filePath);
  589. goto loser;
  590.     }
  591.     fileBits->data = (unsigned char*)asn1Buf;
  592.     fileBits->len  = fileLen;
  593.     return;
  594.  loser:
  595.     if (asn1Buf) {
  596.         PORT_Free(asn1Buf);
  597.     }
  598.     fileBits->data = NULL;
  599.     fileBits->len  = 0;
  600. int
  601. DecodeCMMFCertRepContent(char *derFile)
  602. {
  603.     int         fileLen=0;
  604.     char       *asn1Buf;
  605.     SECItem     fileBits;
  606.     CMMFCertRepContent *certRepContent;
  607.     GetBitsFromFile(derFile, &fileBits);
  608.     if (fileBits.data == NULL) {
  609.         printf("Could not get bits from file %sn", derFile);
  610.         return 304;
  611.     }
  612.     asn1Buf = (char*)fileBits.data;
  613.     fileLen = fileBits.len;
  614.     certRepContent = CMMF_CreateCertRepContentFromDER(db, asn1Buf, fileLen);
  615.     if (certRepContent == NULL) {
  616.         printf ("Error while decoding %sn", derFile);
  617. return 303;
  618.     }
  619.     CMMF_DestroyCertRepContent(certRepContent);
  620.     PORT_Free(asn1Buf);
  621.     return 0;
  622. }
  623. int
  624. DoCMMFStuff(char *configdir)
  625. {
  626.     CMMFCertResponse   *certResp=NULL, *certResp2=NULL, *certResponses[3];
  627.     CMMFCertRepContent *certRepContent=NULL;
  628.     CERTCertificate    *cert=NULL, *caCert=NULL;
  629.     CERTCertList       *list=NULL;
  630.     PRFileDesc         *fileDesc=NULL;
  631.     char                filePath[PATH_LEN];
  632.     int                 rv = 0;
  633.     long                random;
  634.     CMMFKeyRecRepContent       *repContent=NULL;
  635.     SECKEYPrivateKey           *privKey = NULL;
  636.     SECKEYPublicKey *caPubKey;
  637.     SECStatus        srv;
  638.     SECItem          fileBits;
  639.     
  640.     certResp = CMMF_CreateCertResponse(0xff123);
  641.     CMMF_CertResponseSetPKIStatusInfoStatus(certResp, cmmfGranted);
  642.     cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), personalCert);
  643.     if (cert == NULL) {
  644.         printf ("Could not find the certificate for %sn", personalCert);
  645.         rv = 416;
  646.         goto finish;
  647.     } 
  648.     CMMF_CertResponseSetCertificate(certResp, cert);
  649.     certResp2 = CMMF_CreateCertResponse(0xff122);
  650.     CMMF_CertResponseSetPKIStatusInfoStatus(certResp2, cmmfGranted);
  651.     CMMF_CertResponseSetCertificate(certResp2, cert);
  652.     
  653.     certResponses[0] = certResp;
  654.     certResponses[1] = NULL;
  655.     certResponses[2] = NULL;
  656.     certRepContent = CMMF_CreateCertRepContent();
  657.     CMMF_CertRepContentSetCertResponses(certRepContent, certResponses, 1);
  658.     list = CERT_GetCertChainFromCert(cert, PR_Now(), certUsageEmailSigner);
  659.     CMMF_CertRepContentSetCAPubs(certRepContent, list);
  660.     PR_snprintf(filePath, PATH_LEN, "%s/%s", configdir, "CertRepContent.der");
  661.     fileDesc = PR_Open (filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 
  662. 0666);
  663.     if (fileDesc == NULL) {
  664.         printf ("Could not open file %sn", filePath);
  665. rv = 400;
  666. goto finish;
  667.     }
  668.     
  669.     srv = CMMF_EncodeCertRepContent(certRepContent, WriteItOut, 
  670.     (void*)fileDesc);
  671.     PORT_Assert (srv == SECSuccess);
  672.     PR_Close(fileDesc);
  673.     rv = DecodeCMMFCertRepContent(filePath);
  674.     if (rv != 0) {
  675.         goto finish;
  676.     }
  677.     random = 0xa4e7;
  678.     caCert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), 
  679.      caCertName);
  680.     if (caCert == NULL) {
  681.         printf ("Could not get the certifcate for %sn", caCertName);
  682. rv = 411;
  683. goto finish;
  684.     }
  685.     repContent = CMMF_CreateKeyRecRepContent();
  686.     if (repContent == NULL) {
  687.         printf ("Could not allocate a CMMFKeyRecRepContent structuren");
  688. rv = 407;
  689. goto finish;
  690.     }
  691.     srv = CMMF_KeyRecRepContentSetPKIStatusInfoStatus(repContent, 
  692.       cmmfGrantedWithMods);
  693.     if (srv != SECSuccess) {
  694.         printf ("Error trying to set PKIStatusInfo for "
  695. "CMMFKeyRecRepContent.n");
  696. rv = 406;
  697. goto finish;
  698.     }
  699.     srv = CMMF_KeyRecRepContentSetNewSignCert(repContent, cert);
  700.     if (srv != SECSuccess) {
  701.         printf ("Error trying to set the new signing certificate for "
  702. "key recoveryn");
  703. rv = 408;
  704. goto finish;
  705.     }
  706.     srv = CMMF_KeyRecRepContentSetCACerts(repContent, list);
  707.     if (srv != SECSuccess) {
  708.         printf ("Errory trying to add the list of CA certs to the "
  709. "CMMFKeyRecRepContent structure.n");
  710. rv = 409;
  711. goto finish;
  712.     }
  713.     privKey = PK11_FindKeyByAnyCert(cert, NULL);
  714.     if (privKey == NULL) {
  715.         printf ("Could not get the private key associated with then"
  716. "certificate %sn", personalCert);
  717. rv = 410;
  718. goto finish;
  719.     }
  720.     caPubKey = CERT_ExtractPublicKey(caCert);
  721.     if (caPubKey == NULL) {
  722.         printf ("Could not extract the public from the "
  723. "certificate for n%sn", caCertName);
  724. rv = 412;
  725. goto finish;
  726.     }
  727.     CERT_DestroyCertificate(caCert);
  728.     caCert = NULL;
  729.     srv = CMMF_KeyRecRepContentSetCertifiedKeyPair(repContent, cert, privKey,
  730.    caPubKey);
  731.     SECKEY_DestroyPrivateKey(privKey);
  732.     SECKEY_DestroyPublicKey(caPubKey);
  733.     if (srv != SECSuccess) {
  734.         printf ("Could not set the Certified Key Pairn");
  735. rv = 413;
  736. goto finish;
  737.     }
  738.     PR_snprintf(filePath, PATH_LEN, "%s/%s", configdir, 
  739. "KeyRecRepContent.der");
  740.     fileDesc = PR_Open (filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 
  741. 0666);
  742.     if (fileDesc == NULL) {
  743.         printf ("Could not open file %sn", filePath);
  744. rv = 414;
  745. goto finish;
  746.     }
  747.     
  748.     srv = CMMF_EncodeKeyRecRepContent(repContent, WriteItOut, 
  749.       (void*)fileDesc);
  750.     PORT_Assert (srv == SECSuccess);
  751.     PR_Close(fileDesc);
  752.     CMMF_DestroyKeyRecRepContent(repContent);
  753.     GetBitsFromFile(filePath, &fileBits);
  754.     repContent = 
  755.         CMMF_CreateKeyRecRepContentFromDER(db, (const char *) fileBits.data,
  756.    fileBits.len);
  757.     if (repContent == NULL) {
  758.         printf ("ERROR: CMMF_CreateKeyRecRepContentFromDER failed on file:n"
  759. "t%sn", filePath);
  760. rv = 415;
  761. goto finish;
  762.     }
  763.  finish:
  764.     if (repContent) {
  765.         CMMF_DestroyKeyRecRepContent(repContent);
  766.     }
  767.     if (cert) {
  768.         CERT_DestroyCertificate(cert);
  769.     }
  770.     if (list) {
  771.         CERT_DestroyCertList(list);
  772.     }
  773.     if (certResp) {
  774.         CMMF_DestroyCertResponse(certResp);
  775.     }
  776.     if (certResp2) {
  777.         CMMF_DestroyCertResponse(certResp2);
  778.     }
  779.     if (certRepContent) {
  780.         CMMF_DestroyCertRepContent(certRepContent);
  781.     }
  782.     return rv;
  783. }
  784. static CK_MECHANISM_TYPE
  785. mapWrapKeyType(KeyType keyType)
  786. {
  787.     switch (keyType) {
  788.     case rsaKey:
  789.         return CKM_RSA_PKCS;
  790.     default:
  791.         break;
  792.     }
  793.     return CKM_INVALID_MECHANISM;
  794. #define KNOWN_MESSAGE_LENGTH 20 /*160 bits*/
  795. int
  796. DoKeyRecovery(char *configdir, SECKEYPrivateKey *privKey)
  797. {
  798.     SECKEYPublicKey *pubKey;
  799.     PK11SlotInfo    *slot;
  800.     CK_OBJECT_HANDLE id;
  801.     CK_MECHANISM     mech = { CKM_INVALID_MECHANISM, NULL, 0};
  802.     unsigned char *known_message = (unsigned char*)"Known Crypto Message";
  803.     unsigned char  plaintext[KNOWN_MESSAGE_LENGTH];
  804.     char filePath[PATH_LEN];
  805.     CK_RV            crv;
  806.     unsigned char   *ciphertext;
  807.     CK_ULONG         max_bytes_encrypted, bytes_encrypted;
  808.     unsigned char   *text_compared;
  809.     CK_ULONG         bytes_compared, bytes_decrypted;
  810.     SECKEYPrivateKey *unwrappedPrivKey, *caPrivKey;
  811.     CMMFKeyRecRepContent *keyRecRep;
  812.     SECStatus rv;
  813.     CERTCertificate *caCert, *myCert;
  814.     SECKEYPublicKey *caPubKey;
  815.     PRFileDesc *fileDesc;
  816.     SECItem fileBits, nickname;
  817.     CMMFCertifiedKeyPair *certKeyPair;
  818.     /*caCert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), 
  819.      caCertName);*/
  820.     myCert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), personalCert);
  821.     if (myCert == NULL) {
  822.         printf ("Could not find the certificate for %sn", personalCert);
  823.         return 700;
  824.     }
  825.     caCert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), 
  826.      recoveryEncrypter);
  827.     if (caCert == NULL) {
  828.         printf ("Could not find the certificate for %sn", recoveryEncrypter);
  829.         return 701;
  830.     }
  831.     caPubKey = CERT_ExtractPublicKey(caCert);
  832.     pubKey = SECKEY_ConvertToPublicKey(privKey);
  833.     max_bytes_encrypted = PK11_GetPrivateModulusLen(privKey);
  834.     slot = PK11_GetBestSlot(mapWrapKeyType(privKey->keyType), NULL);
  835.     id = PK11_ImportPublicKey(slot, pubKey, PR_FALSE);
  836.     switch(privKey->keyType) {
  837.     case rsaKey:
  838.         mech.mechanism = CKM_RSA_PKCS;
  839. break;
  840.     case dsaKey:
  841.         mech.mechanism = CKM_DSA;
  842. break;
  843.     case dhKey:
  844.         mech.mechanism = CKM_DH_PKCS_DERIVE;
  845. break;
  846.     default:
  847.         printf ("Bad Key type in key recovery.n");
  848. return 512;
  849.     }
  850.     PK11_EnterSlotMonitor(slot);
  851.     crv = PK11_GETTAB(slot)->C_EncryptInit(slot->session, &mech, id);
  852.     if (crv != CKR_OK) {
  853.         PK11_ExitSlotMonitor(slot);
  854. PK11_FreeSlot(slot);
  855. printf ("C_EncryptInit failed in KeyRecoveryn");
  856. return 500;
  857.     }
  858.     ciphertext = PORT_NewArray(unsigned char, max_bytes_encrypted);
  859.     if (ciphertext == NULL) {
  860.         PK11_ExitSlotMonitor(slot);
  861. PK11_FreeSlot(slot);
  862. printf ("Could not allocate memory for ciphertext.n");
  863. return 501;
  864.     }
  865.     bytes_encrypted = max_bytes_encrypted;
  866.     crv = PK11_GETTAB(slot)->C_Encrypt(slot->session, 
  867.        known_message,
  868.        KNOWN_MESSAGE_LENGTH,
  869.        ciphertext,
  870.        &bytes_encrypted);
  871.     PK11_ExitSlotMonitor(slot);
  872.     PK11_FreeSlot(slot);
  873.     if (crv != CKR_OK) {
  874.        PORT_Free(ciphertext);
  875.        return 502;
  876.     }
  877.     /* Always use the smaller of these two values . . . */
  878.     bytes_compared = ( bytes_encrypted > KNOWN_MESSAGE_LENGTH )
  879.                       ? KNOWN_MESSAGE_LENGTH
  880.                       : bytes_encrypted;
  881.  
  882.     /* If there was a failure, the plaintext */
  883.     /* goes at the end, therefore . . .      */
  884.     text_compared = ( bytes_encrypted > KNOWN_MESSAGE_LENGTH )
  885.                     ? (ciphertext + bytes_encrypted -
  886.        KNOWN_MESSAGE_LENGTH )
  887.                      : ciphertext;  
  888.     keyRecRep = CMMF_CreateKeyRecRepContent();
  889.     if (keyRecRep == NULL) {
  890.         PORT_Free(ciphertext);
  891. PK11_FreeSlot(slot);
  892. CMMF_DestroyKeyRecRepContent(keyRecRep);
  893. printf ("Could not allocate a CMMFKeyRecRepContent structre.n");
  894. return 503;
  895.     }
  896.     rv = CMMF_KeyRecRepContentSetPKIStatusInfoStatus(keyRecRep,
  897.      cmmfGranted);
  898.     if (rv != SECSuccess) {
  899.         PORT_Free(ciphertext);
  900. PK11_FreeSlot(slot);
  901. CMMF_DestroyKeyRecRepContent(keyRecRep);
  902. printf ("Could not set the status for the KeyRecRepContentn");
  903. return 504;
  904.     }
  905.     /* The myCert here should correspond to the certificate corresponding
  906.      * to the private key, but for this test any certificate will do.
  907.      */
  908.     rv = CMMF_KeyRecRepContentSetCertifiedKeyPair(keyRecRep, myCert,
  909.   privKey, caPubKey);
  910.     if (rv != SECSuccess) {
  911.         PORT_Free(ciphertext);
  912. PK11_FreeSlot(slot);
  913. CMMF_DestroyKeyRecRepContent(keyRecRep);
  914. printf ("Could not set the Certified Key Pairn");
  915. return 505;
  916.     }
  917.     PR_snprintf(filePath, PATH_LEN, "%s/%s", configdir, 
  918. "KeyRecRepContent.der");
  919.     fileDesc = PR_Open (filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 
  920. 0666);
  921.     if (fileDesc == NULL) {
  922.         PORT_Free(ciphertext);
  923. PK11_FreeSlot(slot);
  924. CMMF_DestroyKeyRecRepContent(keyRecRep);
  925.         printf ("Could not open file %sn", filePath);
  926. return 506;
  927.     }
  928.     rv = CMMF_EncodeKeyRecRepContent(keyRecRep, WriteItOut, fileDesc);
  929.     CMMF_DestroyKeyRecRepContent(keyRecRep);
  930.     PR_Close(fileDesc);
  931.     if (rv != SECSuccess) {
  932.         PORT_Free(ciphertext);
  933. PK11_FreeSlot(slot);
  934. printf ("Error while encoding CMMFKeyRecRepContentn");
  935. return 507;
  936.     }
  937.     GetBitsFromFile(filePath, &fileBits);
  938.     if (fileBits.data == NULL) {
  939.         PORT_Free(ciphertext);
  940. PK11_FreeSlot(slot);
  941.         printf ("Could not get the bits from file %sn", filePath);
  942. return 508;
  943.     }
  944.     keyRecRep = 
  945.         CMMF_CreateKeyRecRepContentFromDER(db,(const char*)fileBits.data,
  946.    fileBits.len);
  947.     if (keyRecRep == NULL) {
  948.         printf ("Could not decode the KeyRecRepContent in file %sn", 
  949. filePath);
  950. PORT_Free(ciphertext);
  951. PK11_FreeSlot(slot);
  952. return 509;
  953.     }
  954.     caPrivKey = PK11_FindKeyByAnyCert(caCert, NULL);
  955.     if (CMMF_KeyRecRepContentGetPKIStatusInfoStatus(keyRecRep) != 
  956.                                                       cmmfGranted) {
  957.         PORT_Free(ciphertext);
  958. PK11_FreeSlot(slot);
  959. CMMF_DestroyKeyRecRepContent(keyRecRep);
  960. printf ("A bad status came back with the "
  961. "KeyRecRepContent structuren");
  962. return 510;
  963.     }
  964. #define NICKNAME "Key Recovery Test Key"
  965.     nickname.data = (unsigned char*)NICKNAME;
  966.     nickname.len  = PORT_Strlen(NICKNAME);
  967.     certKeyPair = CMMF_KeyRecRepContentGetCertKeyAtIndex(keyRecRep, 0);
  968.     CMMF_DestroyKeyRecRepContent(keyRecRep);
  969.     rv = CMMF_CertifiedKeyPairUnwrapPrivKey(certKeyPair,
  970.     caPrivKey,
  971.     &nickname,
  972.     PK11_GetInternalKeySlot(),
  973.     db,
  974.     &unwrappedPrivKey, NULL);
  975.     CMMF_DestroyCertifiedKeyPair(certKeyPair);
  976.     if (rv != SECSuccess) {
  977.         printf ("Unwrapping the private key failed.n");
  978. return 511;
  979.     }
  980.     /*Now let's try to decrypt the ciphertext with the "recovered" key*/
  981.     PK11_EnterSlotMonitor(slot);
  982.     crv = 
  983.       PK11_GETTAB(slot)->C_DecryptInit(unwrappedPrivKey->pkcs11Slot->session,
  984.        &mech,
  985.        unwrappedPrivKey->pkcs11ID);
  986.     if (crv != CKR_OK) {
  987.         PK11_ExitSlotMonitor(slot);
  988. PORT_Free(ciphertext);
  989. PK11_FreeSlot(slot);
  990. printf ("Decrypting with the recovered key failed.n");
  991. return 513;
  992.     }
  993.     bytes_decrypted = KNOWN_MESSAGE_LENGTH;
  994.     crv = PK11_GETTAB(slot)->C_Decrypt(unwrappedPrivKey->pkcs11Slot->session,
  995.        ciphertext, 
  996.        bytes_encrypted, plaintext,
  997.        &bytes_decrypted);
  998.     SECKEY_DestroyPrivateKey(unwrappedPrivKey);
  999.     PK11_ExitSlotMonitor(slot);
  1000.     PORT_Free(ciphertext);
  1001.     if (crv != CKR_OK) {
  1002.         PK11_FreeSlot(slot);
  1003. printf ("Decrypting the ciphertext with recovered key failed.n");
  1004. return 514;
  1005.     }
  1006.     if ((bytes_decrypted != KNOWN_MESSAGE_LENGTH) || 
  1007. (PORT_Memcmp(plaintext, known_message, KNOWN_MESSAGE_LENGTH) != 0)) {
  1008.         PK11_FreeSlot(slot);
  1009. printf ("The recovered plaintext does not equal the known message:n"
  1010. "tKnown message:       %sn"
  1011. "tRecovered plaintext: %sn", known_message, plaintext);
  1012. return 515;
  1013.     }
  1014.     return 0;
  1015. }
  1016. int
  1017. DoChallengeResponse(char *configdir, SECKEYPrivateKey *privKey,
  1018.     SECKEYPublicKey *pubKey)
  1019. {
  1020.     CMMFPOPODecKeyChallContent *chalContent = NULL;
  1021.     CMMFPOPODecKeyRespContent  *respContent = NULL;
  1022.     CERTCertificate            *myCert      = NULL;
  1023.     CERTGeneralName            *myGenName   = NULL;
  1024.     PRArenaPool                *poolp       = NULL;
  1025.     SECItem                     DecKeyChallBits;
  1026.     long                       *randomNums;
  1027.     int                         numChallengesFound=0;
  1028.     int                         numChallengesSet = 1,i;
  1029.     long                        retrieved;
  1030.     char                        filePath[PATH_LEN];
  1031.     RNGContext                 *rng;
  1032.     SECStatus                   rv;
  1033.     PRFileDesc                 *fileDesc;
  1034.     SECItem                    *publicValue, *keyID;
  1035.     SECKEYPrivateKey           *foundPrivKey;
  1036.     chalContent = CMMF_CreatePOPODecKeyChallContent();
  1037.     myCert = CERT_FindCertByNickname(db, personalCert);
  1038.     if (myCert == NULL) {
  1039.         printf ("Could not find the certificate for %sn", personalCert);
  1040.         return 900;
  1041.     }
  1042.     poolp = PORT_NewArena(1024);
  1043.     if (poolp == NULL) {
  1044.         printf("Could no allocate a new arena in DoChallengeResponsen");
  1045. return 901;
  1046.     }
  1047.     myGenName = CERT_GetCertificateNames(myCert, poolp);
  1048.     if (myGenName == NULL) {
  1049.         printf ("Could not get the general names for %s certificaten", 
  1050. personalCert);
  1051. return 902;
  1052.     }
  1053.     randomNums = PORT_ArenaNewArray(poolp,long, numChallengesSet);
  1054.     rng = RNG_CreateContext();
  1055.     RNG_GenerateRandomBytes(rng, randomNums, numChallengesSet*sizeof(long));
  1056.     for (i=0; i<numChallengesSet; i++) {
  1057. rv = CMMF_POPODecKeyChallContentSetNextChallenge(chalContent,
  1058.  randomNums[i],
  1059.  myGenName,
  1060.  pubKey,
  1061.  NULL);
  1062.     }
  1063.     RNG_DestroyContext(rng, PR_TRUE);
  1064.     if (rv != SECSuccess) {
  1065.         printf ("Could not set the challenge in DoChallengeResponsen");
  1066. return 903;
  1067.     }
  1068.     PR_snprintf(filePath, PATH_LEN, "%s/POPODecKeyChallContent.der", 
  1069. configdir);
  1070.     fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
  1071.        0666);
  1072.     if (fileDesc == NULL) {
  1073.         printf ("Could not open file %sn", filePath);
  1074. return 904;
  1075.     }
  1076.     rv = CMMF_EncodePOPODecKeyChallContent(chalContent,WriteItOut, 
  1077.    (void*)fileDesc);
  1078.     PR_Close(fileDesc);
  1079.     CMMF_DestroyPOPODecKeyChallContent(chalContent);
  1080.     if (rv != SECSuccess) {
  1081.         printf ("Could not encode the POPODecKeyChallContent.n");
  1082. return 905;
  1083.     }
  1084.     GetBitsFromFile(filePath, &DecKeyChallBits);
  1085.     chalContent = 
  1086.       CMMF_CreatePOPODecKeyChallContentFromDER
  1087.       ((const char*)DecKeyChallBits.data, DecKeyChallBits.len);
  1088.     PORT_Free(DecKeyChallBits.data);
  1089.     if (chalContent == NULL) {
  1090.         printf ("Could not create the POPODecKeyChallContent from DERn");
  1091. return 906;
  1092.     }
  1093.     numChallengesFound = 
  1094.       CMMF_POPODecKeyChallContentGetNumChallenges(chalContent);
  1095.     if (numChallengesFound != numChallengesSet) {
  1096.         printf ("Number of Challenges Found (%d) does not equal the number "
  1097. "set (%d)n", numChallengesFound, numChallengesSet);
  1098. return 907;
  1099.     }
  1100.     for (i=0; i<numChallengesSet; i++) {
  1101.         publicValue = CMMF_POPODecKeyChallContentGetPublicValue(chalContent, i);
  1102. if (publicValue == NULL) {
  1103.   printf("Could not get the public value for challenge at index %dn",
  1104.  i);
  1105.   return 908;
  1106. }
  1107. keyID = PK11_MakeIDFromPubKey(publicValue);
  1108. if (keyID == NULL) {
  1109.     printf ("Could not make the keyID from the public valuen");
  1110.     return 909;
  1111. }
  1112. foundPrivKey = PK11_FindKeyByKeyID(privKey->pkcs11Slot,keyID, NULL);
  1113. if (foundPrivKey == NULL) {
  1114.     printf ("Could not find the private key corresponding to the public"
  1115.     " value.n");
  1116.     return 910;
  1117. }
  1118. rv = CMMF_POPODecKeyChallContDecryptChallenge(chalContent, i, 
  1119.       foundPrivKey);
  1120. if (rv != SECSuccess) {
  1121.     printf ("Could not decrypt the challenge at index %dn", i);
  1122.     return 911;
  1123. }
  1124. rv = CMMF_POPODecKeyChallContentGetRandomNumber(chalContent, i, 
  1125. &retrieved);
  1126. if (rv != SECSuccess) {
  1127.     printf ("Could not get the random number from the challenge at "
  1128.     "index %dn", i);
  1129.     return 912;
  1130. }
  1131. if (retrieved != randomNums[i]) {
  1132.     printf ("Retrieved the number (%d), expected (%d)n", retrieved,
  1133.     randomNums[i]);
  1134.     return 913;
  1135. }
  1136.     }
  1137.     CMMF_DestroyPOPODecKeyChallContent(chalContent);
  1138.     PR_snprintf(filePath, PATH_LEN, "%s/POPODecKeyRespContent.der", 
  1139. configdir);
  1140.     fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
  1141.        0666);
  1142.     if (fileDesc == NULL) {
  1143.         printf ("Could not open file %sn", filePath);
  1144. return 914;
  1145.     }
  1146.     rv = CMMF_EncodePOPODecKeyRespContent(randomNums, numChallengesSet,
  1147.   WriteItOut, fileDesc);
  1148.     PR_Close(fileDesc);
  1149.     if (rv != 0) {
  1150.         printf ("Could not encode the POPODecKeyRespContentn");
  1151. return 915;
  1152.     }
  1153.     GetBitsFromFile(filePath, &DecKeyChallBits);
  1154.     respContent = 
  1155.      CMMF_CreatePOPODecKeyRespContentFromDER((const char*)DecKeyChallBits.data,
  1156.      DecKeyChallBits.len);
  1157.     if (respContent == NULL) {
  1158.         printf ("Could not decode the contents of the file %sn", filePath);
  1159. return 916;
  1160.     }
  1161.     numChallengesFound = 
  1162.          CMMF_POPODecKeyRespContentGetNumResponses(respContent);
  1163.     if (numChallengesFound != numChallengesSet) {
  1164.         printf ("Number of responses found (%d) does not match the number "
  1165. "of challenges set (%d)n",
  1166. numChallengesFound, numChallengesSet);
  1167. return 917;
  1168.     }
  1169.     for (i=0; i<numChallengesSet; i++) {
  1170.         rv = CMMF_POPODecKeyRespContentGetResponse(respContent, i, &retrieved);
  1171. if (rv != SECSuccess) {
  1172.     printf ("Could not retrieve the response at index %dn", i);
  1173.     return 918;
  1174. }
  1175. if (retrieved != randomNums[i]) {
  1176.     printf ("Retrieved the number (%ld), expected (%ld)n", retrieved,
  1177.     randomNums[i]);
  1178.     return 919;
  1179. }
  1180.   
  1181.     }
  1182.     CMMF_DestroyPOPODecKeyRespContent(respContent);
  1183.     return 0;
  1184. }
  1185. char *
  1186. certdb_name_cb(void *arg, int dbVersion)
  1187. {
  1188.     char *configdir = (char *)arg;
  1189.     char *dbver;
  1190.     switch (dbVersion) {
  1191.     case 7:
  1192.        dbver = "7";
  1193.        break;
  1194.     case 6:
  1195.        dbver = "6";
  1196.        break;
  1197.     case 5:
  1198.         dbver = "5";
  1199.     case 4:
  1200.     default:
  1201.         dbver = "";
  1202. break;
  1203.     }
  1204.     return PR_smprintf("%s/cert%s.db", configdir, dbver);
  1205. }
  1206. SECStatus
  1207. OpenCertDB(char *configdir)
  1208. {
  1209.     CERTCertDBHandle *certdb;
  1210.     SECStatus         status = SECFailure;
  1211.     certdb = PORT_ZNew(CERTCertDBHandle);
  1212.     if (certdb == NULL) {
  1213.         goto loser;
  1214.     }
  1215.     status = CERT_OpenCertDB(certdb, PR_TRUE, certdb_name_cb, configdir);
  1216.     if (status == SECSuccess) {
  1217.         CERT_SetDefaultCertDB(certdb);
  1218. db = certdb;
  1219.     } else {
  1220.         PORT_Free(certdb);
  1221.     }
  1222.  loser:
  1223.     return status;
  1224. }
  1225. char *
  1226. keydb_name_cb(void *arg, int dbVersion)
  1227. {
  1228.     char *configdir = (char*) arg;
  1229.     char *dbver;
  1230.     switch(dbVersion){
  1231.     case 3:
  1232.         dbver = "3";
  1233. break;
  1234.     case 2:
  1235.     default:
  1236.         dbver = "";
  1237. break;
  1238.     }
  1239.     return PR_smprintf("%s/key%s.db", configdir, dbver);
  1240. }
  1241. SECStatus
  1242. OpenKeyDB(char *configdir)
  1243. {
  1244.     SECKEYKeyDBHandle *keydb;
  1245.     keydb = SECKEY_OpenKeyDB(PR_FALSE, keydb_name_cb, configdir);
  1246.     if (keydb == NULL) {
  1247.         return SECFailure;
  1248.     }
  1249.     SECKEY_SetDefaultKeyDB(keydb);
  1250.     return SECSuccess;
  1251. }
  1252. SECStatus
  1253. OpenSecModDB(char *configdir)
  1254. {
  1255.     char *secmodname = PR_smprintf("%d/secmod.db", configdir);
  1256.     if (secmodname == NULL) {
  1257.         return SECFailure;
  1258.     }
  1259.     SECMOD_init(secmodname);
  1260.     return SECSuccess;
  1261. }
  1262. void
  1263. CloseHCL(void)
  1264. {
  1265.     CERTCertDBHandle  *certHandle;
  1266.     SECKEYKeyDBHandle *keyHandle;
  1267.     
  1268.     certHandle = CERT_GetDefaultCertDB();
  1269.     if (certHandle) {
  1270.         CERT_ClosePermCertDB(certHandle);
  1271.     }
  1272.     keyHandle = SECKEY_GetDefaultKeyDB();
  1273.     if (keyHandle) {
  1274.         SECKEY_CloseKeyDB(keyHandle);
  1275.     }
  1276. }
  1277. SECStatus
  1278. InitHCL(char *configdir)
  1279. {
  1280.     SECStatus status;
  1281.     SECStatus rv = SECFailure;
  1282.     RNG_RNGInit();
  1283.     RNG_SystemInfoForRNG();
  1284.     status = OpenCertDB(configdir);
  1285.     if (status != SECSuccess) {
  1286.         goto loser;
  1287.     }
  1288.     
  1289.     status = OpenKeyDB(configdir);
  1290.     if (status != SECSuccess) {
  1291.         goto loser;
  1292.     }
  1293.     
  1294.     status = OpenSecModDB(configdir);
  1295.     if (status != SECSuccess) {
  1296.        goto loser;
  1297.     }
  1298.     
  1299.     rv = SECSuccess;
  1300.  loser:
  1301.     if (rv != SECSuccess) {
  1302.         CloseHCL();
  1303.     }
  1304.     return rv;
  1305. }
  1306. void
  1307. Usage (void)
  1308. {
  1309.     printf ("Usage:n"
  1310.     "tcrmftest -d [Database Directory] -p [Personal Cert]n"
  1311.     "t         -e [Encrypter] -s [CA Certificate]nn"
  1312.     "Database Directoryn"
  1313.     "tThis is the directory where the key3.db, cert7.db, andn"
  1314.     "tsecmod.db files are located.  This is also the directoryn"
  1315.     "twhere the program will place CRMF/CMMF der filesn"
  1316.     "Personal Certn"
  1317.     "tThis is the certificate that already exists in the certn"
  1318.     "tdatabase to use while encoding the response.  The privaten"
  1319.     "tkey associated with the certificate must also exist in then"
  1320.     "tkey database.n"
  1321.     "Encryptern"
  1322.     "tThis is the certificate to use when encrypting the the n"
  1323.     "tkey recovery response.  The private key for this certn"
  1324.     "tmust also be present in the key database.n"
  1325.     "CA Certificaten"
  1326.     "tThis is the nickname of the certificate to use as then"
  1327.     "tCA when doing all of the encoding.n");
  1328. }
  1329. int
  1330. main(int argc, char **argv) 
  1331. {
  1332.     CRMFCertRequest *certReq, *certReq2;
  1333.     CRMFCertReqMsg *certReqMsg;
  1334.     CRMFCertReqMsg *secondMsg;
  1335.     char *configdir;
  1336.     int irv;
  1337.     SECStatus rv;
  1338.     SECKEYPrivateKey *privKey;
  1339.     SECKEYPublicKey  *pubKey;
  1340.     int o;
  1341.     PRBool hclInit = PR_FALSE, pArg = PR_FALSE, eArg = PR_FALSE, 
  1342.            sArg = PR_FALSE;
  1343.     printf ("ncrmftest v1.0n");
  1344.     while (-1 != (o = getopt(argc, argv, "d:p:e:s:"))) {
  1345.         switch(o) {
  1346. case 'd':
  1347.     configdir = PORT_Strdup(optarg);
  1348.     rv = InitHCL(configdir);
  1349.     if (rv != SECSuccess) {
  1350.         printf ("InitHCL failedn");
  1351. return 101;
  1352.     }       
  1353.     hclInit = PR_TRUE;
  1354.     break;
  1355. case 'p':
  1356.     personalCert = PORT_Strdup(optarg);
  1357.     if (personalCert == NULL) {
  1358.         return 603;
  1359.     }
  1360.     pArg = PR_TRUE;
  1361.     break;
  1362. case 'e':
  1363.     recoveryEncrypter = PORT_Strdup(optarg);
  1364.     if (recoveryEncrypter == NULL) {
  1365.         return 602;
  1366.     }
  1367.     eArg = PR_TRUE;
  1368.     break;
  1369. case 's':
  1370.     caCertName = PORT_Strdup(optarg);
  1371.     if (caCertName == NULL) {
  1372.         return 604;
  1373.     }
  1374.     sArg = PR_TRUE;
  1375.     break;
  1376. default:
  1377.   Usage();
  1378.   return 601;
  1379. }
  1380.     }
  1381.     if (!hclInit || !pArg || !eArg || !sArg) {
  1382.         Usage();
  1383. return 600;
  1384.     }
  1385.     InitPKCS11();
  1386.     
  1387.     irv = CreateCertRequest(&certReq, &privKey, &pubKey);
  1388.     if (irv != 0 || certReq == NULL) {
  1389.         goto loser;
  1390.     }
  1391.     certReqMsg = CRMF_CreateCertReqMsg();
  1392.     secondMsg  = CRMF_CreateCertReqMsg();
  1393.     CRMF_CertReqMsgSetCertRequest(certReqMsg, certReq);
  1394.     CRMF_CertReqMsgSetCertRequest(secondMsg,  certReq);
  1395.     irv = AddProofOfPossession(certReqMsg, privKey, pubKey, crmfSignature);
  1396.     irv = AddProofOfPossession(secondMsg, privKey, pubKey, crmfKeyAgreement);
  1397.     irv = Encode (certReqMsg, secondMsg, configdir);
  1398.     if (irv != 0) {
  1399.         goto loser;
  1400.     }
  1401.     
  1402.     rv = CRMF_DestroyCertRequest (certReq);
  1403.     if (rv != SECSuccess) {
  1404.         printf ("Error when destroy certificate request.n");
  1405. irv = 100;
  1406. goto loser;
  1407.     }
  1408.     rv = CRMF_DestroyCertReqMsg(certReqMsg);
  1409.     CRMF_DestroyCertReqMsg(secondMsg);
  1410.     irv = Decode (configdir);
  1411.     if (irv != 0) {
  1412.         printf("Error while decodingn");
  1413. goto loser;
  1414.     }
  1415.     if ((irv = DoCMMFStuff(configdir)) != 0) {
  1416.         printf ("CMMF tests failed.n");
  1417. goto loser;
  1418.     }
  1419.     if ((irv = DoKeyRecovery(configdir, privKey)) != 0) {
  1420.         printf ("Error doing key recoveryn");
  1421. goto loser;
  1422.     }
  1423.     if ((irv = DoChallengeResponse(configdir, privKey, pubKey)) != 0) {
  1424.         printf ("Error doing challenge-responsen");
  1425. goto loser;
  1426.     }
  1427.     printf ("Exiting successfully!!!nn");
  1428.     irv = 0;
  1429.  loser:
  1430.     CloseHCL();
  1431.     PORT_Free(configdir);
  1432.     return irv;
  1433. }