/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * This program does 5 separate functions.  By default, it does them all.
 * It can be told to do any subset of them.
 * It does them in this order:
 *
 * 1. Generate file of CRMF cert requests.
 *     Generates 2 keys pairs, one for signing, one for encryption.
 *     Can generate RSA or DSA (XXX - DSA is only useful for signing).
 *     Generate a cert request for each of the two public keys.
 *     Generate a single CRMF cert request message that requests both certs.
 *     Leave the generated CRMF request message in file
 *         configdir/CertReqMessages.der
 *
 * 2. Decode CRMF Request(s) Message.
 *  Reads in the file   configdir/CertReqMessages.der
 *  (either generated by step 1 above, or user supplied).
 *  Decodes it.  NOTHING MORE.  Drops these decoded results on the floor.
 *  The CMMF response (below) contains a completely unrelated cert.  :-(
 *
 * 3. CMMF "Stuff".
 *  a)  Generates a CMMF response, containing a single cert chain, as if
 *  it was a response to a received CRMF request.  But the cert is
 *  simply a user cert from the user's local soft token, whose
 *  nickname is given in the -p option.  The CMMF response has no
 *  relationship to the request generated above.  The CMMF message
 *  is placed in configdir/CertRepContent.der.
 *  b)  Decodes the newly generated CMMF response found in file
 *  configdir/CertRepContent.der and discards the result.  8-/
 *  c)  Generate a CMMF Key Escrow message
 *      needs 2 nicknames:
 *      It takes the public and private keys for the cert identified
 *      by -p nickname, and wraps them with a sym key that is in turn
 *      wrapped with the pubkey in the CA cert, whose nickname is
 *      given with the -s option.
 *      Store the message in configdir/KeyRecRepContent.der
 *  d)  Decode the CMMF Key Escrow message generated just above.
 *      Get it from file configdir/KeyRecRepContent.der
 *      This is just a decoder test.  Results are discarded.
 *
 * 4. Key Recovery
 *  This code does not yet compile, and what it was intended to do
 *  has not been fully determined.
 *
 * 5. Challenge/Response.
 *  Haven't analyzed this code yet.
 *
 *
 */

/* KNOWN BUGS:
** 1. generates BOTH signing and encryption cert requests, even for DSA keys.
**
** 2. Does not verify the siganture in the "Proof of Posession" in the
**  decoded cert requests.  It only checks syntax of the POP.
** 3. CMMF "Stuff" should be broken up into separate steps, each of
**  which may be optionally selected.
*/

#include <stdio.h>
#include "nspr.h"
#include "nss.h"
#include "crmf.h"
#include "secerr.h"
#include "pk11func.h"
#include "keyhi.h"
#include "cmmf.h"
#include "plgetopt.h"
#include "secutil.h"
#include "pk11pqg.h"

#if 0
#include "pkcs11.h"
#include "secmod.h"
#include "secmodi.h"
#include "pqggen.h"
#include "secmod.h"
#include "secmodi.h"
#include "pkcs11.h"
#include "secitem.h"
#include "secasn1.h"
#include "sechash.h"
#endif

#define MAX_KEY_LEN 512
#define PATH_LEN 150
#define BUFF_SIZE 150
#define UID_BITS 800
#define BPB 8
#define CRMF_FILE "CertReqMessages.der"

PRTime notBefore;
char *personalCert = NULL;
char *recoveryEncrypter = NULL;
char *caCertName = NULL;
static secuPWData pwdata = { PW_NONE, 0 };
char *configdir;
PRBool doingDSA = PR_FALSE;

CERTCertDBHandle *db;

typedef struct {
    SECKEYPrivateKey *privKey;
    SECKEYPublicKey *pubKey;
    CRMFCertRequest *certReq;
    CRMFCertReqMsg *certReqMsg;
} TESTKeyPair;

void
debug_test(SECItem *src, char *filePath)
{
    PRFileDesc *fileDesc;

    fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
                       0666);
    if (fileDesc == NULL) {
        printf("Could not cretae file %s.\n", filePath);
        return;
    }
    PR_Write(fileDesc, src->data, src->len);
}

SECStatus
get_serial_number(long *dest)
{
    SECStatus rv;

    if (dest == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = PK11_GenerateRandom((unsigned char *)dest, sizeof(long));
    if (rv != SECSuccess) {
        /* PK11_GenerateRandom calls PORT_SetError */
        return SECFailure;
    }
    /* make serial number positive */
    if (*dest < 0L)
        *dest = -*dest;
    return SECSuccess;
}

PK11RSAGenParams *
GetRSAParams(void)
{
    PK11RSAGenParams *rsaParams;

    rsaParams = PORT_ZNew(PK11RSAGenParams);

    if (rsaParams == NULL)
        return NULL;

    rsaParams->keySizeInBits = MAX_KEY_LEN;
    rsaParams->pe = 0x10001;

    return rsaParams;
}

PQGParams *
GetDSAParams(void)
{
    PQGParams *params = NULL;
    PQGVerify *vfy = NULL;

    SECStatus rv;

    rv = PK11_PQG_ParamGen(0, &params, &vfy);
    if (rv != SECSuccess) {
        return NULL;
    }
    PK11_PQG_DestroyVerify(vfy);
    return params;
}

/* Generate a key pair, and then generate a subjectPublicKeyInfo
** for the public key in that pair.  return all 3.
*/
CERTSubjectPublicKeyInfo *
GetSubjectPubKeyInfo(TESTKeyPair *pair)
{
    CERTSubjectPublicKeyInfo *spki = NULL;
    SECKEYPrivateKey *privKey = NULL;
    SECKEYPublicKey *pubKey = NULL;
    PK11SlotInfo *keySlot = NULL;

    keySlot = PK11_GetInternalKeySlot();
    PK11_Authenticate(keySlot, PR_FALSE, &pwdata);

    if (!doingDSA) {
        PK11RSAGenParams *rsaParams = GetRSAParams();
        if (rsaParams == NULL) {
            PK11_FreeSlot(keySlot);
            return NULL;
        }
        privKey = PK11_GenerateKeyPair(keySlot, CKM_RSA_PKCS_KEY_PAIR_GEN,
                                       (void *)rsaParams, &pubKey, PR_FALSE,
                                       PR_FALSE, &pwdata);
    } else {
        PQGParams *dsaParams = GetDSAParams();
        if (dsaParams == NULL) {
            PK11_FreeSlot(keySlot);
            return NULL;
        }
        privKey = PK11_GenerateKeyPair(keySlot, CKM_DSA_KEY_PAIR_GEN,
                                       (void *)dsaParams, &pubKey, PR_FALSE,
                                       PR_FALSE, &pwdata);
    }
    PK11_FreeSlot(keySlot);
    if (privKey == NULL || pubKey == NULL) {
        if (pubKey) {
            SECKEY_DestroyPublicKey(pubKey);
        }
        if (privKey) {
            SECKEY_DestroyPrivateKey(privKey);
        }
        return NULL;
    }

    spki = SECKEY_CreateSubjectPublicKeyInfo(pubKey);
    pair->privKey = privKey;
    pair->pubKey = pubKey;
    return spki;
}

SECStatus
InitPKCS11(void)
{
    PK11SlotInfo *keySlot;

    PK11_SetPasswordFunc(SECU_GetModulePassword);

    keySlot = PK11_GetInternalKeySlot();

    if (PK11_NeedUserInit(keySlot) && PK11_NeedLogin(keySlot)) {
        if (SECU_ChangePW(keySlot, NULL, NULL) != SECSuccess) {
            printf("Initializing the PINs failed.\n");
            return SECFailure;
        }
    }

    PK11_FreeSlot(keySlot);
    return SECSuccess;
}

void
WriteItOut(void *arg, const char *buf, unsigned long len)
{
    PRFileDesc *fileDesc = (PRFileDesc *)arg;

    PR_Write(fileDesc, (void *)buf, len);
}

CRMFCertExtCreationInfo *
GetExtensions(void)
{
    unsigned char keyUsage[4] = { 0x03, 0x02, 0x07, KU_DIGITAL_SIGNATURE };
    /* What are these magic numbers? */
    SECItem data = { 0, NULL, 0 };
    CRMFCertExtension *extension;
    CRMFCertExtCreationInfo *extInfo =
        PORT_ZNew(CRMFCertExtCreationInfo);

    data.data = keyUsage;
    data.len = sizeof keyUsage;

    extension =
        CRMF_CreateCertExtension(SEC_OID_X509_KEY_USAGE, PR_FALSE, &data);
    if (extension && extInfo) {
        extInfo->numExtensions = 1;
        extInfo->extensions = PORT_ZNewArray(CRMFCertExtension *, 1);
        extInfo->extensions[0] = extension;
    }
    return extInfo;
}

void
FreeExtInfo(CRMFCertExtCreationInfo *extInfo)
{
    int i;

    for (i = 0; i < extInfo->numExtensions; i++) {
        CRMF_DestroyCertExtension(extInfo->extensions[i]);
    }
    PORT_Free(extInfo->extensions);
    PORT_Free(extInfo);
}

int
InjectCertName(CRMFCertRequest *certReq,
               CRMFCertTemplateField inTemplateField,
               const char *inNameString)
{
    char *nameStr;
    CERTName *name;
    int irv = 0;

    nameStr = PORT_Strdup(inNameString);
    if (!nameStr)
        return 5;
    name = CERT_AsciiToName(nameStr);
    if (name == NULL) {
        printf("Could not create CERTName structure from %s.\n", nameStr);
        irv = 5;
        goto finish;
    }

    irv = CRMF_CertRequestSetTemplateField(certReq, inTemplateField, (void *)name);
    if (irv != SECSuccess) {
        printf("Could not add name to cert template\n");
        irv = 6;
    }

finish:
    PORT_Free(nameStr);
    if (name)
        CERT_DestroyName(name);
    return irv;
}

int
CreateCertRequest(TESTKeyPair *pair, long inRequestID)
{
    CERTCertificate *caCert;
    CERTSubjectPublicKeyInfo *spki;
    CRMFCertExtCreationInfo *extInfo;
    CRMFCertRequest *certReq;
    CRMFEncryptedKey *encKey;
    CRMFPKIArchiveOptions *pkiArchOpt;
    SECAlgorithmID *algID;
    long serialNumber;
    long version = 3;
    SECStatus rv;
    CRMFValidityCreationInfo validity;
    unsigned char UIDbuf[UID_BITS / BPB];
    SECItem issuerUID = { siBuffer, NULL, 0 };
    SECItem subjectUID = { siBuffer, NULL, 0 };

    /* len in bits */
    issuerUID.data = UIDbuf;
    issuerUID.len = UID_BITS;
    subjectUID.data = UIDbuf;
    subjectUID.len = UID_BITS;

    pair->certReq = NULL;
    certReq = CRMF_CreateCertRequest(inRequestID);
    if (certReq == NULL) {
        printf("Could not initialize a certificate request.\n");
        return 1;
    }

    /* set to version 3 */
    rv = CRMF_CertRequestSetTemplateField(certReq, crmfVersion,
                                          (void *)(&version));
    if (rv != SECSuccess) {
        printf("Could not add the version number to the "
               "Certificate Request.\n");
        CRMF_DestroyCertRequest(certReq);
        return 2;
    }

    /* set serial number */
    if (get_serial_number(&serialNumber) != SECSuccess) {
        printf("Could not generate a serial number for cert request.\n");
        CRMF_DestroyCertRequest(certReq);
        return 3;
    }
    rv = CRMF_CertRequestSetTemplateField(certReq, crmfSerialNumber,
                                          (void *)(&serialNumber));
    if (rv != SECSuccess) {
        printf("Could not add serial number to certificate template\n.");
        CRMF_DestroyCertRequest(certReq);
        return 4;
    }

    /* Set issuer name */
    rv = InjectCertName(certReq, crmfIssuer,
                        "CN=mozilla CA Shack,O=Information Systems");
    if (rv) {
        printf("Could not add issuer to cert template\n");
        CRMF_DestroyCertRequest(certReq);
        return 5;
    }

    /* Set Subject Name */
    rv = InjectCertName(certReq, crmfSubject,
                        "CN=mozilla CA Shack ID,O=Engineering,C=US");
    if (rv) {
        printf("Could not add Subject to cert template\n");
        CRMF_DestroyCertRequest(certReq);
        return 5;
    }

    /* Set Algorithm ID */
    algID = PK11_CreatePBEAlgorithmID(SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC,
                                      1, NULL);
    if (algID == NULL) {
        printf("Couldn't create algorithm ID\n");
        CRMF_DestroyCertRequest(certReq);
        return 9;
    }
    rv = CRMF_CertRequestSetTemplateField(certReq, crmfSigningAlg, (void *)algID);
    SECOID_DestroyAlgorithmID(algID, PR_TRUE);
    if (rv != SECSuccess) {
        printf("Could not add the signing algorithm to the cert template.\n");
        CRMF_DestroyCertRequest(certReq);
        return 10;
    }

    /* Set Validity Dates */
    validity.notBefore = &notBefore;
    validity.notAfter = NULL;
    notBefore = PR_Now();
    rv = CRMF_CertRequestSetTemplateField(certReq, crmfValidity, (void *)(&validity));
    if (rv != SECSuccess) {
        printf("Could not add validity to cert template\n");
        CRMF_DestroyCertRequest(certReq);
        return 11;
    }

    /* Generate a key pair and Add the spki to the request */
    spki = GetSubjectPubKeyInfo(pair);
    if (spki == NULL) {
        printf("Could not create a Subject Public Key Info to add\n");
        CRMF_DestroyCertRequest(certReq);
        return 12;
    }
    rv = CRMF_CertRequestSetTemplateField(certReq, crmfPublicKey, (void *)spki);
    SECKEY_DestroySubjectPublicKeyInfo(spki);
    if (rv != SECSuccess) {
        printf("Could not add the public key to the template\n");
        CRMF_DestroyCertRequest(certReq);
        return 13;
    }

    /* Set the requested isser Unique ID */
    PK11_GenerateRandom(UIDbuf, sizeof UIDbuf);
    CRMF_CertRequestSetTemplateField(certReq, crmfIssuerUID, (void *)&issuerUID);

    /* Set the requested Subject Unique ID */
    PK11_GenerateRandom(UIDbuf, sizeof UIDbuf);
    CRMF_CertRequestSetTemplateField(certReq, crmfSubjectUID, (void *)&subjectUID);

    /* Add extensions - XXX need to understand these magic numbers */
    extInfo = GetExtensions();
    CRMF_CertRequestSetTemplateField(certReq, crmfExtension, (void *)extInfo);
    FreeExtInfo(extInfo);

    /* get the recipient CA's cert */
    caCert = CERT_FindCertByNickname(db, caCertName);
    if (caCert == NULL) {
        printf("Could not find the certificate for %s\n", caCertName);
        CRMF_DestroyCertRequest(certReq);
        return 50;
    }
    encKey = CRMF_CreateEncryptedKeyWithEncryptedValue(pair->privKey, caCert);
    CERT_DestroyCertificate(caCert);
    if (encKey == NULL) {
        printf("Could not create Encrypted Key with Encrypted Value.\n");
        return 14;
    }
    pkiArchOpt = CRMF_CreatePKIArchiveOptions(crmfEncryptedPrivateKey, encKey);
    CRMF_DestroyEncryptedKey(encKey);
    if (pkiArchOpt == NULL) {
        printf("Could not create PKIArchiveOptions.\n");
        return 15;
    }
    rv = CRMF_CertRequestSetPKIArchiveOptions(certReq, pkiArchOpt);
    CRMF_DestroyPKIArchiveOptions(pkiArchOpt);
    if (rv != SECSuccess) {
        printf("Could not add the PKIArchiveControl to Cert Request.\n");
        return 16;
    }
    pair->certReq = certReq;
    return 0;
}

int
Encode(CRMFCertReqMsg *inCertReq1, CRMFCertReqMsg *inCertReq2)
{
    PRFileDesc *fileDesc;
    SECStatus rv;
    int irv = 0;
    CRMFCertReqMsg *msgArr[3];
    char filePath[PATH_LEN];

    PR_snprintf(filePath, PATH_LEN, "%s/%s", configdir, CRMF_FILE);
    fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
                       0666);
    if (fileDesc == NULL) {
        printf("Could not open file %s\n", filePath);
        irv = 14;
        goto finish;
    }
    msgArr[0] = inCertReq1;
    msgArr[1] = inCertReq2;
    msgArr[2] = NULL;
    rv = CRMF_EncodeCertReqMessages(msgArr, WriteItOut, (void *)fileDesc);
    if (rv != SECSuccess) {
        printf("An error occurred while encoding.\n");
        irv = 15;
    }
finish:
    PR_Close(fileDesc);
    return irv;
}

int
AddProofOfPossession(TESTKeyPair *pair,
                     CRMFPOPChoice inPOPChoice)
{

    switch (inPOPChoice) {
        case crmfSignature:
            CRMF_CertReqMsgSetSignaturePOP(pair->certReqMsg, pair->privKey,
                                           pair->pubKey, NULL, NULL, &pwdata);
            break;
        case crmfRAVerified:
            CRMF_CertReqMsgSetRAVerifiedPOP(pair->certReqMsg);
            break;
        case crmfKeyEncipherment:
            CRMF_CertReqMsgSetKeyEnciphermentPOP(pair->certReqMsg,
                                                 crmfSubsequentMessage,
                                                 crmfChallengeResp, NULL);
            break;
        case crmfKeyAgreement: {
            SECItem pendejo;
            unsigned char lame[] = { 0xf0, 0x0f, 0xf0, 0x0f, 0xf0 };

            pendejo.data = lame;
            pendejo.len = 5;

            CRMF_CertReqMsgSetKeyAgreementPOP(pair->certReqMsg, crmfThisMessage,
                                              crmfNoSubseqMess, &pendejo);
        } break;
        default:
            return 1;
    }
    return 0;
}

int
Decode(void)
{
    PRFileDesc *fileDesc;
    CRMFCertReqMsg *certReqMsg;
    CRMFCertRequest *certReq;
    CRMFCertReqMessages *certReqMsgs;
    SECStatus rv;
    int numMsgs, i;
    long lame;
    CRMFGetValidity validity = { NULL, NULL };
    SECItem item = { siBuffer, NULL, 0 };
    char filePath[PATH_LEN];

    PR_snprintf(filePath, PATH_LEN, "%s/%s", configdir, CRMF_FILE);
    fileDesc = PR_Open(filePath, PR_RDONLY, 0644);
    if (fileDesc == NULL) {
        printf("Could not open file %s\n", filePath);
        return 214;
    }
    rv = SECU_FileToItem(&item, fileDesc);
    PR_Close(fileDesc);
    if (rv != SECSuccess) {
        return 215;
    }

    certReqMsgs = CRMF_CreateCertReqMessagesFromDER((char *)item.data, item.len);
    if (certReqMsgs == NULL) {
        printf("Error decoding CertReqMessages.\n");
        return 202;
    }
    numMsgs = CRMF_CertReqMessagesGetNumMessages(certReqMsgs);
    if (numMsgs <= 0) {
        printf("WARNING: The DER contained %d messages.\n", numMsgs);
    }
    for (i = 0; i < numMsgs; i++) {
        printf("crmftest: Processing cert request %d\n", i);
        certReqMsg = CRMF_CertReqMessagesGetCertReqMsgAtIndex(certReqMsgs, i);
        if (certReqMsg == NULL) {
            printf("ERROR: Could not access the message at index %d of %s\n",
                   i, filePath);
        }
        rv = CRMF_CertReqMsgGetID(certReqMsg, &lame);
        if (rv) {
            SECU_PrintError("crmftest", "CRMF_CertReqMsgGetID");
        }
        certReq = CRMF_CertReqMsgGetCertRequest(certReqMsg);
        if (!certReq) {
            SECU_PrintError("crmftest", "CRMF_CertReqMsgGetCertRequest");
        }
        rv = CRMF_CertRequestGetCertTemplateValidity(certReq, &validity);
        if (rv) {
            SECU_PrintError("crmftest", "CRMF_CertRequestGetCertTemplateValidity");
        }
        if (!validity.notBefore) {
            /* We encoded a notBefore, so somthing's wrong if it's not here. */
            printf("ERROR: Validity period notBefore date missing.\n");
        }
        /* XXX It's all parsed now.  We probably should DO SOMETHING with it.
    ** But nope.  We just throw it all away.
    ** Maybe this was intended to be no more than a decoder test.
    */
        CRMF_DestroyGetValidity(&validity);
        CRMF_DestroyCertRequest(certReq);
        CRMF_DestroyCertReqMsg(certReqMsg);
    }
    CRMF_DestroyCertReqMessages(certReqMsgs);
    SECITEM_FreeItem(&item, PR_FALSE);
    return 0;
}

int
GetBitsFromFile(const char *filePath, SECItem *item)
{
    PRFileDesc *fileDesc;
    SECStatus rv;

    fileDesc = PR_Open(filePath, PR_RDONLY, 0644);
    if (fileDesc == NULL) {
        printf("Could not open file %s\n", filePath);
        return 14;
    }

    rv = SECU_FileToItem(item, fileDesc);
    PR_Close(fileDesc);

    if (rv != SECSuccess) {
        item->data = NULL;
        item->len = 0;
        return 15;
    }
    return 0;
}

int
DecodeCMMFCertRepContent(char *derFile)
{
    CMMFCertRepContent *certRepContent;
    int irv = 0;
    SECItem fileBits = { siBuffer, NULL, 0 };

    GetBitsFromFile(derFile, &fileBits);
    if (fileBits.data == NULL) {
        printf("Could not get bits from file %s\n", derFile);
        return 304;
    }
    certRepContent = CMMF_CreateCertRepContentFromDER(db,
                                                      (char *)fileBits.data, fileBits.len);
    if (certRepContent == NULL) {
        printf("Error while decoding %s\n", derFile);
        irv = 303;
    } else {
        /* That was fun.  Now, let's throw it away!  */
        CMMF_DestroyCertRepContent(certRepContent);
    }
    SECITEM_FreeItem(&fileBits, PR_FALSE);
    return irv;
}

int
EncodeCMMFCertReply(const char *filePath,
                    CERTCertificate *cert,
                    CERTCertList *list)
{
    int rv = 0;
    SECStatus srv;
    PRFileDesc *fileDesc = NULL;
    CMMFCertRepContent *certRepContent = NULL;
    CMMFCertResponse *certResp = NULL;
    CMMFCertResponse *certResponses[3];

    certResp = CMMF_CreateCertResponse(0xff123);
    CMMF_CertResponseSetPKIStatusInfoStatus(certResp, cmmfGranted);

    CMMF_CertResponseSetCertificate(certResp, cert);

    certResponses[0] = certResp;
    certResponses[1] = NULL;
    certResponses[2] = NULL;

    certRepContent = CMMF_CreateCertRepContent();
    CMMF_CertRepContentSetCertResponses(certRepContent, certResponses, 1);

    CMMF_CertRepContentSetCAPubs(certRepContent, list);

    fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
                       0666);
    if (fileDesc == NULL) {
        printf("Could not open file %s\n", filePath);
        rv = 400;
        goto finish;
    }

    srv = CMMF_EncodeCertRepContent(certRepContent, WriteItOut,
                                    (void *)fileDesc);
    PR_Close(fileDesc);
    if (srv != SECSuccess) {
        printf("CMMF_EncodeCertRepContent failed,\n");
        rv = 401;
    }
finish:
    if (certRepContent) {
        CMMF_DestroyCertRepContent(certRepContent);
    }
    if (certResp) {
        CMMF_DestroyCertResponse(certResp);
    }
    return rv;
}

/* Extract the public key from the cert whose nickname is given. */
int
extractPubKeyFromNamedCert(const char *nickname, SECKEYPublicKey **pPubKey)
{
    CERTCertificate *caCert = NULL;
    SECKEYPublicKey *caPubKey = NULL;
    int rv = 0;

    caCert = CERT_FindCertByNickname(db, (char *)nickname);
    if (caCert == NULL) {
        printf("Could not get the certifcate for %s\n", caCertName);
        rv = 411;
        goto finish;
    }
    caPubKey = CERT_ExtractPublicKey(caCert);
    if (caPubKey == NULL) {
        printf("Could not extract the public from the "
               "certificate for \n%s\n",
               caCertName);
        rv = 412;
    }
finish:
    *pPubKey = caPubKey;
    CERT_DestroyCertificate(caCert);
    caCert = NULL;
    return rv;
}

int
EncodeCMMFRecoveryMessage(const char *filePath,
                          CERTCertificate *cert,
                          CERTCertList *list)
{
    SECKEYPublicKey *caPubKey = NULL;
    SECKEYPrivateKey *privKey = NULL;
    CMMFKeyRecRepContent *repContent = NULL;
    PRFileDesc *fileDesc;
    int rv = 0;
    SECStatus srv;

    /* Extract the public key from the cert whose nickname is given in
    ** the -s option.
    */
    rv = extractPubKeyFromNamedCert(caCertName, &caPubKey);
    if (rv)
        goto finish;

    repContent = CMMF_CreateKeyRecRepContent();
    if (repContent == NULL) {
        printf("Could not allocate a CMMFKeyRecRepContent structure\n");
        rv = 407;
        goto finish;
    }
    srv = CMMF_KeyRecRepContentSetPKIStatusInfoStatus(repContent,
                                                      cmmfGrantedWithMods);
    if (srv != SECSuccess) {
        printf("Error trying to set PKIStatusInfo for "
               "CMMFKeyRecRepContent.\n");
        rv = 406;
        goto finish;
    }
    srv = CMMF_KeyRecRepContentSetNewSignCert(repContent, cert);
    if (srv != SECSuccess) {
        printf("Error trying to set the new signing certificate for "
               "key recovery\n");
        rv = 408;
        goto finish;
    }
    srv = CMMF_KeyRecRepContentSetCACerts(repContent, list);
    if (srv != SECSuccess) {
        printf("Errory trying to add the list of CA certs to the "
               "CMMFKeyRecRepContent structure.\n");
        rv = 409;
        goto finish;
    }
    privKey = PK11_FindKeyByAnyCert(cert, &pwdata);
    if (privKey == NULL) {
        printf("Could not get the private key associated with the\n"
               "certificate %s\n",
               personalCert);
        rv = 410;
        goto finish;
    }

    srv = CMMF_KeyRecRepContentSetCertifiedKeyPair(repContent, cert, privKey,
                                                   caPubKey);
    if (srv != SECSuccess) {
        printf("Could not set the Certified Key Pair\n");
        rv = 413;
        goto finish;
    }
    fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
                       0666);
    if (fileDesc == NULL) {
        printf("Could not open file %s\n", filePath);
        rv = 414;
        goto finish;
    }

    srv = CMMF_EncodeKeyRecRepContent(repContent, WriteItOut,
                                      (void *)fileDesc);
    PR_Close(fileDesc);
    if (srv != SECSuccess) {
        printf("CMMF_EncodeKeyRecRepContent failed\n");
        rv = 415;
    }
finish:
    if (privKey)
        SECKEY_DestroyPrivateKey(privKey);
    if (caPubKey)
        SECKEY_DestroyPublicKey(caPubKey);
    if (repContent)
        CMMF_DestroyKeyRecRepContent(repContent);
    return rv;
}

int
decodeCMMFRecoveryMessage(const char *filePath)
{
    CMMFKeyRecRepContent *repContent = NULL;
    int rv = 0;
    SECItem fileBits = { siBuffer, NULL, 0 };

    GetBitsFromFile(filePath, &fileBits);
    if (!fileBits.len) {
        rv = 451;
        goto finish;
    }
    repContent =
        CMMF_CreateKeyRecRepContentFromDER(db, (const char *)fileBits.data,
                                           fileBits.len);
    if (repContent == NULL) {
        printf("ERROR: CMMF_CreateKeyRecRepContentFromDER failed on file:\n"
               "\t%s\n",
               filePath);
        rv = 452;
    }
finish:
    if (repContent) {
        CMMF_DestroyKeyRecRepContent(repContent);
    }
    SECITEM_FreeItem(&fileBits, PR_FALSE);
    return rv;
}

int
DoCMMFStuff(void)
{
    CERTCertificate *cert = NULL;
    CERTCertList *list = NULL;
    int rv = 0;
    char filePath[PATH_LEN];

    /* Do common setup for the following steps.
    */
    PR_snprintf(filePath, PATH_LEN, "%s/%s", configdir, "CertRepContent.der");

    cert = CERT_FindCertByNickname(db, personalCert);
    if (cert == NULL) {
        printf("Could not find the certificate for %s\n", personalCert);
        rv = 416;
        goto finish;
    }
    list = CERT_GetCertChainFromCert(cert, PR_Now(), certUsageEmailSigner);
    if (list == NULL) {
        printf("Could not find the certificate chain for %s\n", personalCert);
        rv = 418;
        goto finish;
    }

    /* a) Generate the CMMF response message, using a user cert named
    **    by -p option, rather than a cert generated from the CRMF
    **    request itself.   The CMMF message is placed in
    **    configdir/CertRepContent.der.
    */
    rv = EncodeCMMFCertReply(filePath, cert, list);
    if (rv != 0) {
        goto finish;
    }

    /* b) Decode the CMMF Cert granting message encoded just above,
    **    found in configdir/CertRepContent.der.
    **    This only tests the decoding.  The decoded content is discarded.
    */
    rv = DecodeCMMFCertRepContent(filePath);
    if (rv != 0) {
        goto finish;
    }

    /* c) Generate a CMMF Key Excrow message
    **    It takes the public and private keys for the cert identified
    **    by -p nickname, and wraps them with a sym key that is in turn
    **    wrapped with the pubkey in the CA cert, whose nickname is
    **    given by the -s option.
    **    Store the message in configdir/KeyRecRepContent.der
    */
    PR_snprintf(filePath, PATH_LEN, "%s/%s", configdir,
                "KeyRecRepContent.der");

    rv = EncodeCMMFRecoveryMessage(filePath, cert, list);
    if (rv)
        goto finish;

    /* d) Decode the CMMF Key Excrow message generated just above.
    **    Get it from file configdir/KeyRecRepContent.der
    **    This is just a decoder test.  Results are discarded.
    */

    rv = decodeCMMFRecoveryMessage(filePath);

finish:
    if (cert) {
        CERT_DestroyCertificate(cert);
    }
    if (list) {
        CERT_DestroyCertList(list);
    }
    return rv;
}

#define KNOWN_MESSAGE_LENGTH 20 /*160 bits*/

int
DoKeyRecovery(SECKEYPrivateKey *privKey)
{
#ifdef DOING_KEY_RECOVERY /* Doesn't compile yet. */
    SECKEYPublicKey *pubKey;
    PK11SlotInfo *slot;
    unsigned char *ciphertext;
    unsigned char *text_compared;
    SECKEYPrivateKey *unwrappedPrivKey;
    SECKEYPrivateKey *caPrivKey;
    CMMFKeyRecRepContent *keyRecRep;
    CMMFCertifiedKeyPair *certKeyPair;
    CERTCertificate *caCert;
    CERTCertificate *myCert;
    SECKEYPublicKey *caPubKey;
    PRFileDesc *fileDesc;
    CK_ULONG max_bytes_encrypted;
    CK_ULONG bytes_encrypted;
    CK_ULONG bytes_compared;
    CK_ULONG bytes_decrypted;
    CK_RV crv;
    CK_OBJECT_HANDLE id;
    CK_MECHANISM mech = { CKM_INVALID_MECHANISM, NULL, 0 };
    SECStatus rv;
    SECItem fileBits;
    SECItem nickname;
    unsigned char plaintext[KNOWN_MESSAGE_LENGTH];
    char filePath[PATH_LEN];
    static const unsigned char known_message[] = { "Known Crypto Message" };

    /*caCert = CERT_FindCertByNickname(db, caCertName);*/
    myCert = CERT_FindCertByNickname(db, personalCert);
    if (myCert == NULL) {
        printf("Could not find the certificate for %s\n", personalCert);
        return 700;
    }
    caCert = CERT_FindCertByNickname(db, recoveryEncrypter);
    if (caCert == NULL) {
        printf("Could not find the certificate for %s\n", recoveryEncrypter);
        return 701;
    }
    caPubKey = CERT_ExtractPublicKey(caCert);
    pubKey = SECKEY_ConvertToPublicKey(privKey);
    max_bytes_encrypted = PK11_GetPrivateModulusLen(privKey);
    slot = PK11_GetBestSlotWithAttributes(mapWrapKeyType(privKey->keyType),
                                          CKF_ENCRYPT, 0, NULL);
    id = PK11_ImportPublicKey(slot, pubKey, PR_FALSE);

    switch (privKey->keyType) {
        case rsaKey:
            mech.mechanism = CKM_RSA_PKCS;
            break;
        case dsaKey:
            mech.mechanism = CKM_DSA;
            break;
        case dhKey:
            mech.mechanism = CKM_DH_PKCS_DERIVE;
            break;
        default:
            printf("Bad Key type in key recovery.\n");
            return 512;
    }
    PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_EncryptInit(slot->session, &mech, id);
    if (crv != CKR_OK) {
        PK11_ExitSlotMonitor(slot);
        PK11_FreeSlot(slot);
        printf("C_EncryptInit failed in KeyRecovery\n");
        return 500;
    }
    ciphertext = PORT_NewArray(unsigned char, max_bytes_encrypted);
    if (ciphertext == NULL) {
        PK11_ExitSlotMonitor(slot);
        PK11_FreeSlot(slot);
        printf("Could not allocate memory for ciphertext.\n");
        return 501;
    }
    bytes_encrypted = max_bytes_encrypted;
    crv = PK11_GETTAB(slot)->C_Encrypt(slot->session,
                                       known_message,
                                       KNOWN_MESSAGE_LENGTH,
                                       ciphertext,
                                       &bytes_encrypted);
    PK11_ExitSlotMonitor(slot);
    PK11_FreeSlot(slot);
    if (crv != CKR_OK) {
        PORT_Free(ciphertext);
        return 502;
    }
    /* Always use the smaller of these two values . . . */
    bytes_compared = (bytes_encrypted > KNOWN_MESSAGE_LENGTH)
                         ? KNOWN_MESSAGE_LENGTH
                         : bytes_encrypted;

    /* If there was a failure, the plaintext */
    /* goes at the end, therefore . . .      */
    text_compared = (bytes_encrypted > KNOWN_MESSAGE_LENGTH)
                        ? (ciphertext + bytes_encrypted -
                           KNOWN_MESSAGE_LENGTH)
                        : ciphertext;

    keyRecRep = CMMF_CreateKeyRecRepContent();
    if (keyRecRep == NULL) {
        PORT_Free(ciphertext);
        PK11_FreeSlot(slot);
        CMMF_DestroyKeyRecRepContent(keyRecRep);
        printf("Could not allocate a CMMFKeyRecRepContent structre.\n");
        return 503;
    }
    rv = CMMF_KeyRecRepContentSetPKIStatusInfoStatus(keyRecRep,
                                                     cmmfGranted);
    if (rv != SECSuccess) {
        PORT_Free(ciphertext);
        PK11_FreeSlot(slot);
        CMMF_DestroyKeyRecRepContent(keyRecRep);
        printf("Could not set the status for the KeyRecRepContent\n");
        return 504;
    }
    /* The myCert here should correspond to the certificate corresponding
     * to the private key, but for this test any certificate will do.
     */
    rv = CMMF_KeyRecRepContentSetCertifiedKeyPair(keyRecRep, myCert,
                                                  privKey, caPubKey);
    if (rv != SECSuccess) {
        PORT_Free(ciphertext);
        PK11_FreeSlot(slot);
        CMMF_DestroyKeyRecRepContent(keyRecRep);
        printf("Could not set the Certified Key Pair\n");
        return 505;
    }
    PR_snprintf(filePath, PATH_LEN, "%s/%s", configdir,
                "KeyRecRepContent.der");
    fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
                       0666);
    if (fileDesc == NULL) {
        PORT_Free(ciphertext);
        PK11_FreeSlot(slot);
        CMMF_DestroyKeyRecRepContent(keyRecRep);
        printf("Could not open file %s\n", filePath);
        return 506;
    }
    rv = CMMF_EncodeKeyRecRepContent(keyRecRep, WriteItOut, fileDesc);
    CMMF_DestroyKeyRecRepContent(keyRecRep);
    PR_Close(fileDesc);

    if (rv != SECSuccess) {
        PORT_Free(ciphertext);
        PK11_FreeSlot(slot);
        printf("Error while encoding CMMFKeyRecRepContent\n");
        return 507;
    }
    GetBitsFromFile(filePath, &fileBits);
    if (fileBits.data == NULL) {
        PORT_Free(ciphertext);
        PK11_FreeSlot(slot);
        printf("Could not get the bits from file %s\n", filePath);
        return 508;
    }
    keyRecRep =
        CMMF_CreateKeyRecRepContentFromDER(db, (const char *)fileBits.data,
                                           fileBits.len);
    if (keyRecRep == NULL) {
        printf("Could not decode the KeyRecRepContent in file %s\n",
               filePath);
        PORT_Free(ciphertext);
        PK11_FreeSlot(slot);
        return 509;
    }
    caPrivKey = PK11_FindKeyByAnyCert(caCert, &pwdata);
    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, &pwdata);
    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;
    }
#endif
    return 0;
}

int
DoChallengeResponse(SECKEYPrivateKey *privKey,
                    SECKEYPublicKey *pubKey)
{
    CMMFPOPODecKeyChallContent *chalContent = NULL;
    CMMFPOPODecKeyRespContent *respContent = NULL;
    CERTCertificate *myCert = NULL;
    CERTGeneralName *myGenName = NULL;
    PLArenaPool *poolp = NULL;
    PRFileDesc *fileDesc;
    SECItem *publicValue;
    SECItem *keyID;
    SECKEYPrivateKey *foundPrivKey;
    long *randomNums;
    int numChallengesFound = 0;
    int numChallengesSet = 1;
    int i;
    long retrieved;
    SECStatus rv;
    SECItem DecKeyChallBits;
    char filePath[PATH_LEN];

    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);
    PK11_GenerateRandom((unsigned char *)randomNums,
                        numChallengesSet * sizeof(long));
    for (i = 0; i < numChallengesSet; i++) {
        rv = CMMF_POPODecKeyChallContentSetNextChallenge(chalContent,
                                                         randomNums[i],
                                                         myGenName,
                                                         pubKey,
                                                         &pwdata);
        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);
    SECITEM_FreeItem(&DecKeyChallBits, PR_FALSE);
    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);
        SECITEM_FreeItem(publicValue, PR_TRUE);
        if (keyID == NULL) {
            printf("Could not make the keyID from the public value\n");
            return 909;
        }
        foundPrivKey = PK11_FindKeyByKeyID(privKey->pkcs11Slot, keyID, &pwdata);
        SECITEM_FreeItem(keyID, PR_TRUE);
        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 (%ld), expected (%ld)\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;
}

int
MakeCertRequest(TESTKeyPair *pair, CRMFPOPChoice inPOPChoice, long inRequestID)
{
    int irv;

    /* Generate a key pair and a cert request for it. */
    irv = CreateCertRequest(pair, inRequestID);
    if (irv != 0 || pair->certReq == NULL) {
        goto loser;
    }

    pair->certReqMsg = CRMF_CreateCertReqMsg();
    if (!pair->certReqMsg) {
        irv = 999;
        goto loser;
    }
    /* copy certReq into certReqMsg */
    CRMF_CertReqMsgSetCertRequest(pair->certReqMsg, pair->certReq);
    irv = AddProofOfPossession(pair, inPOPChoice);
loser:
    return irv;
}

int
DestroyPairReqAndMsg(TESTKeyPair *pair)
{
    SECStatus rv = SECSuccess;
    int irv = 0;

    if (pair->certReq) {
        rv = CRMF_DestroyCertRequest(pair->certReq);
        pair->certReq = NULL;
        if (rv != SECSuccess) {
            printf("Error when destroying cert request.\n");
            irv = 100;
        }
    }
    if (pair->certReqMsg) {
        rv = CRMF_DestroyCertReqMsg(pair->certReqMsg);
        pair->certReqMsg = NULL;
        if (rv != SECSuccess) {
            printf("Error when destroying cert request msg.\n");
            if (!irv)
                irv = 101;
        }
    }
    return irv;
}

int
DestroyPair(TESTKeyPair *pair)
{
    int irv = 0;

    if (pair->pubKey) {
        SECKEY_DestroyPublicKey(pair->pubKey);
        pair->pubKey = NULL;
    }
    if (pair->privKey) {
        SECKEY_DestroyPrivateKey(pair->privKey);
        pair->privKey = NULL;
    }
    DestroyPairReqAndMsg(pair);
    return irv;
}

int
DoCRMFRequest(TESTKeyPair *signPair, TESTKeyPair *cryptPair)
{
    int irv, tirv = 0;

    /* Generate a key pair and a cert request for it. */
    irv = MakeCertRequest(signPair, crmfSignature, 0x0f020304);
    if (irv != 0 || signPair->certReq == NULL) {
        goto loser;
    }

    if (!doingDSA) {
        irv = MakeCertRequest(cryptPair, crmfKeyAgreement, 0x0f050607);
        if (irv != 0 || cryptPair->certReq == NULL) {
            goto loser;
        }
    }

    /* encode the cert request messages into a unified request message.
    ** leave it in a file with a fixed name.  :(
    */
    irv = Encode(signPair->certReqMsg, cryptPair->certReqMsg);

loser:
    if (signPair->certReq) {
        tirv = DestroyPairReqAndMsg(signPair);
        if (tirv && !irv)
            irv = tirv;
    }
    if (cryptPair->certReq) {
        tirv = DestroyPairReqAndMsg(cryptPair);
        if (tirv && !irv)
            irv = tirv;
    }
    return irv;
}

void
Usage(void)
{
    printf("Usage:\n"
           "\tcrmftest -d [Database Directory] -p [Personal Cert]\n"
           "\t         -e [Encrypter] -s [CA Certificate] [-P password]\n\n"
           "\t         [crmf] [dsa] [decode] [cmmf] [recover] [challenge]\n"
           "\t         [-f password_file]\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");
}

#define TEST_MAKE_CRMF_REQ 0x0001
#define TEST_USE_DSA 0x0002
#define TEST_DECODE_CRMF_REQ 0x0004
#define TEST_DO_CMMF_STUFF 0x0008
#define TEST_KEY_RECOVERY 0x0010
#define TEST_CHALLENGE_RESPONSE 0x0020

SECStatus
parsePositionalParam(const char *arg, PRUint32 *flags)
{
    if (!strcmp(arg, "crmf")) {
        *flags |= TEST_MAKE_CRMF_REQ;
    } else if (!strcmp(arg, "dsa")) {
        *flags |= TEST_MAKE_CRMF_REQ | TEST_USE_DSA;
        doingDSA = PR_TRUE;
    } else if (!strcmp(arg, "decode")) {
        *flags |= TEST_DECODE_CRMF_REQ;
    } else if (!strcmp(arg, "cmmf")) {
        *flags |= TEST_DO_CMMF_STUFF;
    } else if (!strcmp(arg, "recover")) {
        *flags |= TEST_KEY_RECOVERY;
    } else if (!strcmp(arg, "challenge")) {
        *flags |= TEST_CHALLENGE_RESPONSE;
    } else {
        printf("unknown positional paremeter: %s\n", arg);
        return SECFailure;
    }
    return SECSuccess;
}

/* it's not clear, in some cases, whether the desired key is from
** the sign pair or the crypt pair, so we're guessing in some places.
** This define serves to remind us of the places where we're guessing.
*/
#define WHICH_KEY cryptPair

int
main(int argc, char **argv)
{
    TESTKeyPair signPair, cryptPair;
    PLOptState *optstate;
    PLOptStatus status;
    char *password = NULL;
    char *pwfile = NULL;
    int irv = 0;
    PRUint32 flags = 0;
    SECStatus rv;
    PRBool nssInit = PR_FALSE;

    memset(&signPair, 0, sizeof signPair);
    memset(&cryptPair, 0, sizeof cryptPair);
    printf("\ncrmftest v1.0\n");
    optstate = PL_CreateOptState(argc, argv, "d:p:e:s:P:f:");
    while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
        switch (optstate->option) {
            case 'd':
                configdir = PORT_Strdup(optstate->value);
                rv = NSS_Init(configdir);
                if (rv != SECSuccess) {
                    printf("NSS_Init (-d) failed\n");
                    return 101;
                }
                nssInit = PR_TRUE;
                break;
            case 'p':
                personalCert = PORT_Strdup(optstate->value);
                if (personalCert == NULL) {
                    printf("-p  failed\n");
                    return 603;
                }
                break;
            case 'e':
                recoveryEncrypter = PORT_Strdup(optstate->value);
                if (recoveryEncrypter == NULL) {
                    printf("-e  failed\n");
                    return 602;
                }
                break;
            case 's':
                caCertName = PORT_Strdup(optstate->value);
                if (caCertName == NULL) {
                    printf("-s  failed\n");
                    return 604;
                }
                break;
            case 'P':
                password = PORT_Strdup(optstate->value);
                if (password == NULL) {
                    printf("-P  failed\n");
                    return 606;
                }
                pwdata.source = PW_PLAINTEXT;
                pwdata.data = password;
                break;
            case 'f':
                pwfile = PORT_Strdup(optstate->value);
                if (pwfile == NULL) {
                    printf("-f  failed\n");
                    return 607;
                }
                pwdata.source = PW_FROMFILE;
                pwdata.data = pwfile;
                break;
            case 0: /* positional parameter */
                rv = parsePositionalParam(optstate->value, &flags);
                if (rv) {
                    printf("bad positional parameter.\n");
                    return 605;
                }
                break;
            default:
                Usage();
                return 601;
        }
    }
    PL_DestroyOptState(optstate);
    if (status == PL_OPT_BAD || !nssInit) {
        Usage();
        return 600;
    }
    if (!flags)
        flags = ~TEST_USE_DSA;
    db = CERT_GetDefaultCertDB();
    InitPKCS11();

    if (flags & TEST_MAKE_CRMF_REQ) {
        printf("Generating CRMF request\n");
        irv = DoCRMFRequest(&signPair, &cryptPair);
        if (irv)
            goto loser;
    }

    if (flags & TEST_DECODE_CRMF_REQ) {
        printf("Decoding CRMF request\n");
        irv = Decode();
        if (irv != 0) {
            printf("Error while decoding\n");
            goto loser;
        }
    }

    if (flags & TEST_DO_CMMF_STUFF) {
        printf("Doing CMMF Stuff\n");
        if ((irv = DoCMMFStuff()) != 0) {
            printf("CMMF tests failed.\n");
            goto loser;
        }
    }

    if (flags & TEST_KEY_RECOVERY) {
        /* Requires some other options be set.
        ** Once we know exactly what hey are, test for them here.
        */
        printf("Doing Key Recovery\n");
        irv = DoKeyRecovery(WHICH_KEY.privKey);
        if (irv != 0) {
            printf("Error doing key recovery\n");
            goto loser;
        }
    }

    if (flags & TEST_CHALLENGE_RESPONSE) {
        printf("Doing Challenge / Response\n");
        irv = DoChallengeResponse(WHICH_KEY.privKey, WHICH_KEY.pubKey);
        if (irv != 0) {
            printf("Error doing challenge-response\n");
            goto loser;
        }
    }
    printf("Exiting successfully!!!\n\n");
    irv = 0;

loser:
    DestroyPair(&signPair);
    DestroyPair(&cryptPair);
    rv = NSS_Shutdown();
    if (rv) {
        printf("NSS_Shutdown did not shutdown cleanly!\n");
    }
    PORT_Free(configdir);
    if (irv)
        printf("crmftest returning %d\n", irv);
    return irv;
}
