/* 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/. */

#include "seccomon.h"
#include "nss.h"
#include "keyhi.h"
#include "cert.h"
#include "pk11func.h"
#include "secmod.h"
#include "cmmf.h"
#include "crmf.h"
#include "base64.h"
#include "secasn1.h"
#include "cryptohi.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define DEFAULT_ALLOC_SIZE 200
#define DEFAULT_CGI_VARS 20

typedef struct CGIVariableStr {
    char *name;
    char *value;
} CGIVariable;

typedef struct CGIVarTableStr {
    CGIVariable **variables;
    int numVars;
    int numAlloc;
} CGIVarTable;

typedef struct CertResponseInfoStr {
    CERTCertificate *cert;
    long certReqID;
} CertResponseInfo;

typedef struct ChallengeCreationInfoStr {
    long random;
    SECKEYPublicKey *pubKey;
} ChallengeCreationInfo;

char *missingVar = NULL;

/*
 * Error values.
 */
typedef enum {
    NO_ERROR = 0,
    NSS_INIT_FAILED,
    AUTH_FAILED,
    REQ_CGI_VAR_NOT_PRESENT,
    CRMF_REQ_NOT_PRESENT,
    BAD_ASCII_FOR_REQ,
    CGI_VAR_MISSING,
    COULD_NOT_FIND_CA,
    COULD_NOT_DECODE_REQS,
    OUT_OF_MEMORY,
    ERROR_RETRIEVING_REQUEST_MSG,
    ERROR_RETRIEVING_CERT_REQUEST,
    ERROR_RETRIEVING_SUBJECT_FROM_REQ,
    ERROR_RETRIEVING_PUBLIC_KEY_FROM_REQ,
    ERROR_CREATING_NEW_CERTIFICATE,
    COULD_NOT_START_EXTENSIONS,
    ERROR_RETRIEVING_EXT_FROM_REQ,
    ERROR_ADDING_EXT_TO_CERT,
    ERROR_ENDING_EXTENSIONS,
    COULD_NOT_FIND_ISSUER_PRIVATE_KEY,
    UNSUPPORTED_SIGN_OPERATION_FOR_ISSUER,
    ERROR_SETTING_SIGN_ALG,
    ERROR_ENCODING_NEW_CERT,
    ERROR_SIGNING_NEW_CERT,
    ERROR_CREATING_CERT_REP_CONTENT,
    ERROR_CREATING_SINGLE_CERT_RESPONSE,
    ERROR_SETTING_CERT_RESPONSES,
    ERROR_CREATING_CA_LIST,
    ERROR_ADDING_ISSUER_TO_CA_LIST,
    ERROR_ENCODING_CERT_REP_CONTENT,
    NO_POP_FOR_REQUEST,
    UNSUPPORTED_POP,
    ERROR_RETRIEVING_POP_SIGN_KEY,
    ERROR_RETRIEVING_ALG_ID_FROM_SIGN_KEY,
    ERROR_RETRIEVING_SIGNATURE_FROM_POP_SIGN_KEY,
    DO_CHALLENGE_RESPONSE,
    ERROR_RETRIEVING_PUB_KEY_FROM_NEW_CERT,
    ERROR_ENCODING_CERT_REQ_FOR_POP,
    ERROR_VERIFYING_SIGNATURE_POP,
    ERROR_RETRIEVING_PUB_KEY_FOR_CHALL,
    ERROR_CREATING_EMPTY_CHAL_CONTENT,
    ERROR_EXTRACTING_GEN_NAME_FROM_ISSUER,
    ERROR_SETTING_CHALLENGE,
    ERROR_ENCODING_CHALL,
    ERROR_CONVERTING_CHALL_TO_BASE64,
    ERROR_CONVERTING_RESP_FROM_CHALL_TO_BIN,
    ERROR_CREATING_KEY_RESP_FROM_DER,
    ERROR_RETRIEVING_CLIENT_RESPONSE_TO_CHALLENGE,
    ERROR_RETURNED_CHALL_NOT_VALUE_EXPECTED,
    ERROR_GETTING_KEY_ENCIPHERMENT,
    ERROR_NO_POP_FOR_PRIVKEY,
    ERROR_UNSUPPORTED_POPOPRIVKEY_TYPE
} ErrorCode;

const char *
CGITableFindValue(CGIVarTable *varTable, const char *key);

void
spitOutHeaders(void)
{
    printf("Content-type: text/html\n\n");
}

void
dumpRequest(CGIVarTable *varTable)
{
    int i;
    CGIVariable *var;

    printf("<table border=1 cellpadding=1 cellspacing=1 width=\"100%%\">\n");
    printf("<tr><td><b><center>Variable Name<center></b></td>"
           "<td><b><center>Value</center></b></td></tr>\n");
    for (i = 0; i < varTable->numVars; i++) {
        var = varTable->variables[i];
        printf("<tr><td><pre>%s</pre></td><td><pre>%s</pre></td></tr>\n",
               var->name, var->value);
    }
    printf("</table>\n");
}

void
echo_request(CGIVarTable *varTable)
{
    spitOutHeaders();
    printf("<html><head><title>CGI Echo Page</title></head>\n"
           "<body><h1>Got the following request</h1>\n");
    dumpRequest(varTable);
    printf("</body></html>");
}

void
processVariable(CGIVariable *var)
{
    char *plusSign, *percentSign;

    /*First look for all of the '+' and convert them to spaces */
    plusSign = var->value;
    while ((plusSign = strchr(plusSign, '+')) != NULL) {
        *plusSign = ' ';
    }
    percentSign = var->value;
    while ((percentSign = strchr(percentSign, '%')) != NULL) {
        char string[3];
        int value;

        string[0] = percentSign[1];
        string[1] = percentSign[2];
        string[2] = '\0';

        sscanf(string, "%x", &value);
        *percentSign = (char)value;
        memmove(&percentSign[1], &percentSign[3], 1 + strlen(&percentSign[3]));
    }
}

char *
parseNextVariable(CGIVarTable *varTable, char *form_output)
{
    char *ampersand, *equal;
    CGIVariable *var;

    if (varTable->numVars == varTable->numAlloc) {
        CGIVariable **newArr = realloc(varTable->variables,
                                       (varTable->numAlloc + DEFAULT_CGI_VARS) * sizeof(CGIVariable *));
        if (newArr == NULL) {
            return NULL;
        }
        varTable->variables = newArr;
        varTable->numAlloc += DEFAULT_CGI_VARS;
    }
    equal = strchr(form_output, '=');
    if (equal == NULL) {
        return NULL;
    }
    ampersand = strchr(equal, '&');
    if (ampersand == NULL) {
        return NULL;
    }
    equal[0] = '\0';
    if (ampersand != NULL) {
        ampersand[0] = '\0';
    }
    var = malloc(sizeof(CGIVariable));
    var->name = form_output;
    var->value = &equal[1];
    varTable->variables[varTable->numVars] = var;
    varTable->numVars++;
    processVariable(var);
    return (ampersand != NULL) ? &ampersand[1] : NULL;
}

void
ParseInputVariables(CGIVarTable *varTable, char *form_output)
{
    varTable->variables = malloc(sizeof(CGIVariable *) * DEFAULT_CGI_VARS);
    varTable->numVars = 0;
    varTable->numAlloc = DEFAULT_CGI_VARS;
    while (form_output && form_output[0] != '\0') {
        form_output = parseNextVariable(varTable, form_output);
    }
}

const char *
CGITableFindValue(CGIVarTable *varTable, const char *key)
{
    const char *retVal = NULL;
    int i;

    for (i = 0; i < varTable->numVars; i++) {
        if (strcmp(varTable->variables[i]->name, key) == 0) {
            retVal = varTable->variables[i]->value;
            break;
        }
    }
    return retVal;
}

char *
passwordCallback(PK11SlotInfo *slot, PRBool retry, void *arg)
{
    const char *passwd;
    if (retry) {
        return NULL;
    }
    passwd = CGITableFindValue((CGIVarTable *)arg, "dbPassword");
    if (passwd == NULL) {
        return NULL;
    }
    return PORT_Strdup(passwd);
}

ErrorCode
initNSS(CGIVarTable *varTable)
{
    const char *nssDir;
    PK11SlotInfo *keySlot;
    SECStatus rv;

    nssDir = CGITableFindValue(varTable, "NSSDirectory");
    if (nssDir == NULL) {
        missingVar = "NSSDirectory";
        return REQ_CGI_VAR_NOT_PRESENT;
    }
    rv = NSS_Init(nssDir);
    if (rv != SECSuccess) {
        return NSS_INIT_FAILED;
    }
    PK11_SetPasswordFunc(passwordCallback);
    keySlot = PK11_GetInternalKeySlot();
    rv = PK11_Authenticate(keySlot, PR_FALSE, varTable);
    PK11_FreeSlot(keySlot);
    if (rv != SECSuccess) {
        return AUTH_FAILED;
    }
    return NO_ERROR;
}

void
dumpErrorMessage(ErrorCode errNum)
{
    spitOutHeaders();
    printf("<html><head><title>Error</title></head><body><h1>Error processing "
           "data</h1> Received the error %d<p>",
           errNum);
    if (errNum == REQ_CGI_VAR_NOT_PRESENT) {
        printf("The missing variable is %s.", missingVar);
    }
    printf("<i>More useful information here in the future.</i></body></html>");
}

ErrorCode
initOldCertReq(CERTCertificateRequest *oldCertReq,
               CERTName *subject, CERTSubjectPublicKeyInfo *spki)
{
    PLArenaPool *poolp;

    poolp = oldCertReq->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    SEC_ASN1EncodeInteger(poolp, &oldCertReq->version,
                          SEC_CERTIFICATE_VERSION_3);
    CERT_CopyName(poolp, &oldCertReq->subject, subject);
    SECKEY_CopySubjectPublicKeyInfo(poolp, &oldCertReq->subjectPublicKeyInfo,
                                    spki);
    oldCertReq->attributes = NULL;
    return NO_ERROR;
}

ErrorCode
addExtensions(CERTCertificate *newCert, CRMFCertRequest *certReq)
{
    int numExtensions, i;
    void *extHandle;
    ErrorCode rv = NO_ERROR;
    CRMFCertExtension *ext;
    SECStatus srv;

    numExtensions = CRMF_CertRequestGetNumberOfExtensions(certReq);
    if (numExtensions == 0) {
        /* No extensions to add */
        return NO_ERROR;
    }
    extHandle = CERT_StartCertExtensions(newCert);
    if (extHandle == NULL) {
        rv = COULD_NOT_START_EXTENSIONS;
        goto loser;
    }
    for (i = 0; i < numExtensions; i++) {
        ext = CRMF_CertRequestGetExtensionAtIndex(certReq, i);
        if (ext == NULL) {
            rv = ERROR_RETRIEVING_EXT_FROM_REQ;
        }
        srv = CERT_AddExtension(extHandle, CRMF_CertExtensionGetOidTag(ext),
                                CRMF_CertExtensionGetValue(ext),
                                CRMF_CertExtensionGetIsCritical(ext), PR_FALSE);
        if (srv != SECSuccess) {
            rv = ERROR_ADDING_EXT_TO_CERT;
        }
    }
    srv = CERT_FinishExtensions(extHandle);
    if (srv != SECSuccess) {
        rv = ERROR_ENDING_EXTENSIONS;
        goto loser;
    }
    return NO_ERROR;
loser:
    return rv;
}

void
writeOutItem(const char *filePath, SECItem *der)
{
    PRFileDesc *outfile;

    outfile = PR_Open(filePath,
                      PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
                      0666);
    PR_Write(outfile, der->data, der->len);
    PR_Close(outfile);
}

ErrorCode
createNewCert(CERTCertificate **issuedCert, CERTCertificateRequest *oldCertReq,
              CRMFCertReqMsg *currReq, CRMFCertRequest *certReq,
              CERTCertificate *issuerCert, CGIVarTable *varTable)
{
    CERTCertificate *newCert = NULL;
    CERTValidity *validity;
    PRExplodedTime printableTime;
    PRTime now, after;
    ErrorCode rv = NO_ERROR;
    SECKEYPrivateKey *issuerPrivKey;
    SECItem derCert = { 0 };
    SECOidTag signTag;
    SECStatus srv;
    long version;

    now = PR_Now();
    PR_ExplodeTime(now, PR_GMTParameters, &printableTime);
    printableTime.tm_month += 9;
    after = PR_ImplodeTime(&printableTime);
    validity = CERT_CreateValidity(now, after);
    newCert = *issuedCert =
        CERT_CreateCertificate(rand(), &(issuerCert->subject), validity,
                               oldCertReq);
    if (newCert == NULL) {
        rv = ERROR_CREATING_NEW_CERTIFICATE;
        goto loser;
    }
    rv = addExtensions(newCert, certReq);
    if (rv != NO_ERROR) {
        goto loser;
    }
    issuerPrivKey = PK11_FindKeyByAnyCert(issuerCert, varTable);
    if (issuerPrivKey == NULL) {
        rv = COULD_NOT_FIND_ISSUER_PRIVATE_KEY;
    }
    signTag = SEC_GetSignatureAlgorithmOidTag(issuerPrivatekey->keytype,
                                              SEC_OID_UNKNOWN);
    if (signTag == SEC_OID_UNKNOWN) {
        rv = UNSUPPORTED_SIGN_OPERATION_FOR_ISSUER;
        goto loser;
    }
    srv = SECOID_SetAlgorithmID(newCert->arena, &newCert->signature,
                                signTag, 0);
    if (srv != SECSuccess) {
        rv = ERROR_SETTING_SIGN_ALG;
        goto loser;
    }
    srv = CRMF_CertRequestGetCertTemplateVersion(certReq, &version);
    if (srv != SECSuccess) {
        /* No version included in the request */
        *(newCert->version.data) = SEC_CERTIFICATE_VERSION_3;
    } else {
        SECITEM_FreeItem(&newCert->version, PR_FALSE);
        SEC_ASN1EncodeInteger(newCert->arena, &newCert->version, version);
    }
    SEC_ASN1EncodeItem(newCert->arena, &derCert, newCert,
                       CERT_CertificateTemplate);
    if (derCert.data == NULL) {
        rv = ERROR_ENCODING_NEW_CERT;
        goto loser;
    }
    srv = SEC_DerSignData(newCert->arena, &(newCert->derCert), derCert.data,
                          derCert.len, issuerPrivKey, signTag);
    if (srv != SECSuccess) {
        rv = ERROR_SIGNING_NEW_CERT;
        goto loser;
    }
#ifdef WRITE_OUT_RESPONSE
    writeOutItem("newcert.der", &newCert->derCert);
#endif
    return NO_ERROR;
loser:
    *issuedCert = NULL;
    if (newCert) {
        CERT_DestroyCertificate(newCert);
    }
    return rv;
}

void
formatCMMFResponse(char *nickname, char *base64Response)
{
    char *currLine, *nextLine;

    printf("var retVal = crypto.importUserCertificates(\"%s\",\n", nickname);
    currLine = base64Response;
    while (1) {
        nextLine = strchr(currLine, '\n');
        if (nextLine == NULL) {
            /* print out the last line here. */
            printf("\"%s\",\n", currLine);
            break;
        }
        nextLine[0] = '\0';
        printf("\"%s\\n\"+\n", currLine);
        currLine = nextLine + 1;
    }
    printf("true);\n"
           "if(retVal == '') {\n"
           "\tdocument.write(\"<h1>New Certificate Successfully Imported.</h1>\");\n"
           "} else {\n"
           "\tdocument.write(\"<h2>Unable to import New Certificate</h2>\");\n"
           "\tdocument.write(\"crypto.importUserCertificates returned <b>\");\n"
           "\tdocument.write(retVal);\n"
           "\tdocument.write(\"</b>\");\n"
           "}\n");
}

void
spitOutCMMFResponse(char *nickname, char *base64Response)
{
    spitOutHeaders();
    printf("<html>\n<head>\n<title>CMMF Resonse Page</title>\n</head>\n\n"
           "<body><h1>CMMF Response Page</h1>\n"
           "<script language=\"JavaScript\">\n"
           "<!--\n");
    formatCMMFResponse(nickname, base64Response);
    printf("// -->\n"
           "</script>\n</body>\n</html>");
}

char *
getNickname(CERTCertificate *cert)
{
    char *nickname;

    if (cert->nickname != NULL) {
        return cert->nickname;
    }
    nickname = CERT_GetCommonName(&cert->subject);
    if (nickname != NULL) {
        return nickname;
    }
    return CERT_NameToAscii(&cert->subject);
}

ErrorCode
createCMMFResponse(CertResponseInfo *issuedCerts, int numCerts,
                   CERTCertificate *issuerCert, char **base64der)
{
    CMMFCertRepContent *certRepContent = NULL;
    ErrorCode rv = NO_ERROR;
    CMMFCertResponse **responses, *currResponse;
    CERTCertList *caList;
    int i;
    SECStatus srv;
    PLArenaPool *poolp;
    SECItem *der;

    certRepContent = CMMF_CreateCertRepContent();
    if (certRepContent == NULL) {
        rv = ERROR_CREATING_CERT_REP_CONTENT;
        goto loser;
    }
    responses = PORT_NewArray(CMMFCertResponse *, numCerts);
    if (responses == NULL) {
        rv = OUT_OF_MEMORY;
        goto loser;
    }
    for (i = 0; i < numCerts; i++) {
        responses[i] = currResponse =
            CMMF_CreateCertResponse(issuedCerts[i].certReqID);
        if (currResponse == NULL) {
            rv = ERROR_CREATING_SINGLE_CERT_RESPONSE;
            goto loser;
        }
        CMMF_CertResponseSetPKIStatusInfoStatus(currResponse, cmmfGranted);
        CMMF_CertResponseSetCertificate(currResponse, issuedCerts[i].cert);
    }
    srv = CMMF_CertRepContentSetCertResponses(certRepContent, responses,
                                              numCerts);
    if (srv != SECSuccess) {
        rv = ERROR_SETTING_CERT_RESPONSES;
        goto loser;
    }
    caList = CERT_NewCertList();
    if (caList == NULL) {
        rv = ERROR_CREATING_CA_LIST;
        goto loser;
    }
    srv = CERT_AddCertToListTail(caList, issuerCert);
    if (srv != SECSuccess) {
        rv = ERROR_ADDING_ISSUER_TO_CA_LIST;
        goto loser;
    }
    srv = CMMF_CertRepContentSetCAPubs(certRepContent, caList);
    CERT_DestroyCertList(caList);
    poolp = PORT_NewArena(1024);
    der = SEC_ASN1EncodeItem(poolp, NULL, certRepContent,
                             CMMFCertRepContentTemplate);
    if (der == NULL) {
        rv = ERROR_ENCODING_CERT_REP_CONTENT;
        goto loser;
    }
#ifdef WRITE_OUT_RESPONSE
    writeOutItem("CertRepContent.der", der);
#endif
    *base64der = BTOA_DataToAscii(der->data, der->len);
    return NO_ERROR;
loser:
    return rv;
}

ErrorCode
issueCerts(CertResponseInfo *issuedCerts, int numCerts,
           CERTCertificate *issuerCert)
{
    ErrorCode rv;
    char *base64Response;

    rv = createCMMFResponse(issuedCerts, numCerts, issuerCert, &base64Response);
    if (rv != NO_ERROR) {
        goto loser;
    }
    spitOutCMMFResponse(getNickname(issuedCerts[0].cert), base64Response);
    return NO_ERROR;
loser:
    return rv;
}

ErrorCode
verifySignature(CGIVarTable *varTable, CRMFCertReqMsg *currReq,
                CRMFCertRequest *certReq, CERTCertificate *newCert)
{
    SECStatus srv;
    ErrorCode rv = NO_ERROR;
    CRMFPOPOSigningKey *signKey = NULL;
    SECAlgorithmID *algID = NULL;
    SECItem *signature = NULL;
    SECKEYPublicKey *pubKey = NULL;
    SECItem *reqDER = NULL;

    srv = CRMF_CertReqMsgGetPOPOSigningKey(currReq, &signKey);
    if (srv != SECSuccess || signKey == NULL) {
        rv = ERROR_RETRIEVING_POP_SIGN_KEY;
        goto loser;
    }
    algID = CRMF_POPOSigningKeyGetAlgID(signKey);
    if (algID == NULL) {
        rv = ERROR_RETRIEVING_ALG_ID_FROM_SIGN_KEY;
        goto loser;
    }
    signature = CRMF_POPOSigningKeyGetSignature(signKey);
    if (signature == NULL) {
        rv = ERROR_RETRIEVING_SIGNATURE_FROM_POP_SIGN_KEY;
        goto loser;
    }
    /* Make the length the number of bytes instead of bits */
    signature->len = (signature->len + 7) / 8;
    pubKey = CERT_ExtractPublicKey(newCert);
    if (pubKey == NULL) {
        rv = ERROR_RETRIEVING_PUB_KEY_FROM_NEW_CERT;
        goto loser;
    }
    reqDER = SEC_ASN1EncodeItem(NULL, NULL, certReq, CRMFCertRequestTemplate);
    if (reqDER == NULL) {
        rv = ERROR_ENCODING_CERT_REQ_FOR_POP;
        goto loser;
    }
    srv = VFY_VerifyDataWithAlgorithmID(reqDER->data, reqDER->len, pubKey,
                                        signature, &algID->algorithm, NULL, varTable);
    if (srv != SECSuccess) {
        rv = ERROR_VERIFYING_SIGNATURE_POP;
        goto loser;
    }
/* Fall thru in successfull case. */
loser:
    if (pubKey != NULL) {
        SECKEY_DestroyPublicKey(pubKey);
    }
    if (reqDER != NULL) {
        SECITEM_FreeItem(reqDER, PR_TRUE);
    }
    if (signature != NULL) {
        SECITEM_FreeItem(signature, PR_TRUE);
    }
    if (algID != NULL) {
        SECOID_DestroyAlgorithmID(algID, PR_TRUE);
    }
    if (signKey != NULL) {
        CRMF_DestroyPOPOSigningKey(signKey);
    }
    return rv;
}

ErrorCode
doChallengeResponse(CGIVarTable *varTable, CRMFCertReqMsg *currReq,
                    CRMFCertRequest *certReq, CERTCertificate *newCert,
                    ChallengeCreationInfo *challs, int *numChall)
{
    CRMFPOPOPrivKey *privKey = NULL;
    CRMFPOPOPrivKeyChoice privKeyChoice;
    SECStatus srv;
    ErrorCode rv = NO_ERROR;

    srv = CRMF_CertReqMsgGetPOPKeyEncipherment(currReq, &privKey);
    if (srv != SECSuccess || privKey == NULL) {
        rv = ERROR_GETTING_KEY_ENCIPHERMENT;
        goto loser;
    }
    privKeyChoice = CRMF_POPOPrivKeyGetChoice(privKey);
    CRMF_DestroyPOPOPrivKey(privKey);
    switch (privKeyChoice) {
        case crmfSubsequentMessage:
            challs = &challs[*numChall];
            challs->random = rand();
            challs->pubKey = CERT_ExtractPublicKey(newCert);
            if (challs->pubKey == NULL) {
                rv =
                    ERROR_RETRIEVING_PUB_KEY_FOR_CHALL;
                goto loser;
            }
            (*numChall)++;
            rv = DO_CHALLENGE_RESPONSE;
            break;
        case crmfThisMessage:
            /* There'd better be a PKIArchiveControl in this message */
            if (!CRMF_CertRequestIsControlPresent(certReq,
                                                  crmfPKIArchiveOptionsControl)) {
                rv =
                    ERROR_NO_POP_FOR_PRIVKEY;
                goto loser;
            }
            break;
        default:
            rv = ERROR_UNSUPPORTED_POPOPRIVKEY_TYPE;
            goto loser;
    }
loser:
    return rv;
}

ErrorCode
doProofOfPossession(CGIVarTable *varTable, CRMFCertReqMsg *currReq,
                    CRMFCertRequest *certReq, CERTCertificate *newCert,
                    ChallengeCreationInfo *challs, int *numChall)
{
    CRMFPOPChoice popChoice;
    ErrorCode rv = NO_ERROR;

    popChoice = CRMF_CertReqMsgGetPOPType(currReq);
    if (popChoice == crmfNoPOPChoice) {
        rv = NO_POP_FOR_REQUEST;
        goto loser;
    }
    switch (popChoice) {
        case crmfSignature:
            rv = verifySignature(varTable, currReq, certReq, newCert);
            break;
        case crmfKeyEncipherment:
            rv = doChallengeResponse(varTable, currReq, certReq, newCert,
                                     challs, numChall);
            break;
        case crmfRAVerified:
        case crmfKeyAgreement:
        default:
            rv = UNSUPPORTED_POP;
            goto loser;
    }
loser:
    return rv;
}

void
convertB64ToJS(char *base64)
{
    int i;

    for (i = 0; base64[i] != '\0'; i++) {
        if (base64[i] == '\n') {
            printf("\\n");
        } else {
            printf("%c", base64[i]);
        }
    }
}

void
formatChallenge(char *chall64, char *certRepContentDER,
                ChallengeCreationInfo *challInfo, int numChalls)
{
    printf("function respondToChallenge() {\n"
           "  var chalForm = document.chalForm;\n\n"
           "  chalForm.CertRepContent.value = '");
    convertB64ToJS(certRepContentDER);
    printf("';\n"
           "  chalForm.ChallResponse.value = crypto.popChallengeResponse('");
    convertB64ToJS(chall64);
    printf("');\n"
           "  chalForm.submit();\n"
           "}\n");
}

void
spitOutChallenge(char *chall64, char *certRepContentDER,
                 ChallengeCreationInfo *challInfo, int numChalls,
                 char *nickname)
{
    int i;

    spitOutHeaders();
    printf("<html>\n"
           "<head>\n"
           "<title>Challenge Page</title>\n"
           "<script language=\"JavaScript\">\n"
           "<!--\n");
    /* The JavaScript function actually gets defined within
   * this function call
   */
    formatChallenge(chall64, certRepContentDER, challInfo, numChalls);
    printf("// -->\n"
           "</script>\n"
           "</head>\n"
           "<body onLoad='respondToChallenge()'>\n"
           "<h1>Cartman is now responding to the Challenge "
           "presented by the CGI</h1>\n"
           "<form action='crmfcgi' method='post' name='chalForm'>\n"
           "<input type='hidden' name=CertRepContent value=''>\n"
           "<input type='hidden' name=ChallResponse value=''>\n");
    for (i = 0; i < numChalls; i++) {
        printf("<input type='hidden' name='chal%d' value='%d'>\n",
               i + 1, challInfo[i].random);
    }
    printf("<input type='hidden' name='nickname' value='%s'>\n", nickname);
    printf("</form>\n</body>\n</html>");
}

ErrorCode
issueChallenge(CertResponseInfo *issuedCerts, int numCerts,
               ChallengeCreationInfo *challInfo, int numChalls,
               CERTCertificate *issuer, CGIVarTable *varTable)
{
    ErrorCode rv = NO_ERROR;
    CMMFPOPODecKeyChallContent *chalContent = NULL;
    int i;
    SECStatus srv;
    PLArenaPool *poolp;
    CERTGeneralName *genName;
    SECItem *challDER = NULL;
    char *chall64, *certRepContentDER;

    rv = createCMMFResponse(issuedCerts, numCerts, issuer,
                            &certRepContentDER);
    if (rv != NO_ERROR) {
        goto loser;
    }
    chalContent = CMMF_CreatePOPODecKeyChallContent();
    if (chalContent == NULL) {
        rv = ERROR_CREATING_EMPTY_CHAL_CONTENT;
        goto loser;
    }
    poolp = PORT_NewArena(1024);
    if (poolp == NULL) {
        rv = OUT_OF_MEMORY;
        goto loser;
    }
    genName = CERT_GetCertificateNames(issuer, poolp);
    if (genName == NULL) {
        rv = ERROR_EXTRACTING_GEN_NAME_FROM_ISSUER;
        goto loser;
    }
    for (i = 0; i < numChalls; i++) {
        srv = CMMF_POPODecKeyChallContentSetNextChallenge(chalContent,
                                                          challInfo[i].random,
                                                          genName,
                                                          challInfo[i].pubKey,
                                                          varTable);
        SECKEY_DestroyPublicKey(challInfo[i].pubKey);
        if (srv != SECSuccess) {
            rv = ERROR_SETTING_CHALLENGE;
            goto loser;
        }
    }
    challDER = SEC_ASN1EncodeItem(NULL, NULL, chalContent,
                                  CMMFPOPODecKeyChallContentTemplate);
    if (challDER == NULL) {
        rv = ERROR_ENCODING_CHALL;
        goto loser;
    }
    chall64 = BTOA_DataToAscii(challDER->data, challDER->len);
    SECITEM_FreeItem(challDER, PR_TRUE);
    if (chall64 == NULL) {
        rv = ERROR_CONVERTING_CHALL_TO_BASE64;
        goto loser;
    }
    spitOutChallenge(chall64, certRepContentDER, challInfo, numChalls,
                     getNickname(issuedCerts[0].cert));
loser:
    return rv;
}

ErrorCode
processRequest(CGIVarTable *varTable)
{
    CERTCertDBHandle *certdb;
    SECKEYKeyDBHandle *keydb;
    CRMFCertReqMessages *certReqs = NULL;
    const char *crmfReq;
    const char *caNickname;
    CERTCertificate *caCert = NULL;
    CertResponseInfo *issuedCerts = NULL;
    CERTSubjectPublicKeyInfo spki = { 0 };
    ErrorCode rv = NO_ERROR;
    PRBool doChallengeResponse = PR_FALSE;
    SECItem der = { 0 };
    SECStatus srv;
    CERTCertificateRequest oldCertReq = { 0 };
    CRMFCertReqMsg **reqMsgs = NULL, *currReq = NULL;
    CRMFCertRequest **reqs = NULL, *certReq = NULL;
    CERTName subject = { 0 };
    int numReqs, i;
    ChallengeCreationInfo *challInfo = NULL;
    int numChalls = 0;

    certdb = CERT_GetDefaultCertDB();
    keydb = SECKEY_GetDefaultKeyDB();
    crmfReq = CGITableFindValue(varTable, "CRMFRequest");
    if (crmfReq == NULL) {
        rv = CGI_VAR_MISSING;
        missingVar = "CRMFRequest";
        goto loser;
    }
    caNickname = CGITableFindValue(varTable, "CANickname");
    if (caNickname == NULL) {
        rv = CGI_VAR_MISSING;
        missingVar = "CANickname";
        goto loser;
    }
    caCert = CERT_FindCertByNickname(certdb, caNickname);
    if (caCert == NULL) {
        rv = COULD_NOT_FIND_CA;
        goto loser;
    }
    srv = ATOB_ConvertAsciiToItem(&der, crmfReq);
    if (srv != SECSuccess) {
        rv = BAD_ASCII_FOR_REQ;
        goto loser;
    }
    certReqs = CRMF_CreateCertReqMessagesFromDER(der.data, der.len);
    SECITEM_FreeItem(&der, PR_FALSE);
    if (certReqs == NULL) {
        rv = COULD_NOT_DECODE_REQS;
        goto loser;
    }
    numReqs = CRMF_CertReqMessagesGetNumMessages(certReqs);
    issuedCerts = PORT_ZNewArray(CertResponseInfo, numReqs);
    challInfo = PORT_ZNewArray(ChallengeCreationInfo, numReqs);
    if (issuedCerts == NULL || challInfo == NULL) {
        rv = OUT_OF_MEMORY;
        goto loser;
    }
    reqMsgs = PORT_ZNewArray(CRMFCertReqMsg *, numReqs);
    reqs = PORT_ZNewArray(CRMFCertRequest *, numReqs);
    if (reqMsgs == NULL || reqs == NULL) {
        rv = OUT_OF_MEMORY;
        goto loser;
    }
    for (i = 0; i < numReqs; i++) {
        currReq = reqMsgs[i] =
            CRMF_CertReqMessagesGetCertReqMsgAtIndex(certReqs, i);
        if (currReq == NULL) {
            rv = ERROR_RETRIEVING_REQUEST_MSG;
            goto loser;
        }
        certReq = reqs[i] = CRMF_CertReqMsgGetCertRequest(currReq);
        if (certReq == NULL) {
            rv = ERROR_RETRIEVING_CERT_REQUEST;
            goto loser;
        }
        srv = CRMF_CertRequestGetCertTemplateSubject(certReq, &subject);
        if (srv != SECSuccess) {
            rv = ERROR_RETRIEVING_SUBJECT_FROM_REQ;
            goto loser;
        }
        srv = CRMF_CertRequestGetCertTemplatePublicKey(certReq, &spki);
        if (srv != SECSuccess) {
            rv = ERROR_RETRIEVING_PUBLIC_KEY_FROM_REQ;
            goto loser;
        }
        rv = initOldCertReq(&oldCertReq, &subject, &spki);
        if (rv != NO_ERROR) {
            goto loser;
        }
        rv = createNewCert(&issuedCerts[i].cert, &oldCertReq, currReq, certReq,
                           caCert, varTable);
        if (rv != NO_ERROR) {
            goto loser;
        }
        rv = doProofOfPossession(varTable, currReq, certReq, issuedCerts[i].cert,
                                 challInfo, &numChalls);
        if (rv != NO_ERROR) {
            if (rv == DO_CHALLENGE_RESPONSE) {
                doChallengeResponse = PR_TRUE;
            } else {
                goto loser;
            }
        }
        CRMF_CertReqMsgGetID(currReq, &issuedCerts[i].certReqID);
        CRMF_DestroyCertReqMsg(currReq);
        CRMF_DestroyCertRequest(certReq);
    }
    if (doChallengeResponse) {
        rv = issueChallenge(issuedCerts, numReqs, challInfo, numChalls, caCert,
                            varTable);
    } else {
        rv = issueCerts(issuedCerts, numReqs, caCert);
    }
loser:
    if (certReqs != NULL) {
        CRMF_DestroyCertReqMessages(certReqs);
    }
    return rv;
}

ErrorCode
processChallengeResponse(CGIVarTable *varTable, const char *certRepContent)
{
    SECItem binDER = { 0 };
    SECStatus srv;
    ErrorCode rv = NO_ERROR;
    const char *clientResponse;
    const char *formChalValue;
    const char *nickname;
    CMMFPOPODecKeyRespContent *respContent = NULL;
    int numResponses, i;
    long curResponse, expectedResponse;
    char cgiChalVar[10];
#ifdef WRITE_OUT_RESPONSE
    SECItem certRepBinDER = { 0 };

    ATOB_ConvertAsciiToItem(&certRepBinDER, certRepContent);
    writeOutItem("challCertRepContent.der", &certRepBinDER);
    PORT_Free(certRepBinDER.data);
#endif
    clientResponse = CGITableFindValue(varTable, "ChallResponse");
    if (clientResponse == NULL) {
        rv = REQ_CGI_VAR_NOT_PRESENT;
        missingVar = "ChallResponse";
        goto loser;
    }
    srv = ATOB_ConvertAsciiToItem(&binDER, clientResponse);
    if (srv != SECSuccess) {
        rv = ERROR_CONVERTING_RESP_FROM_CHALL_TO_BIN;
        goto loser;
    }
    respContent = CMMF_CreatePOPODecKeyRespContentFromDER(binDER.data,
                                                          binDER.len);
    SECITEM_FreeItem(&binDER, PR_FALSE);
    binDER.data = NULL;
    if (respContent == NULL) {
        rv = ERROR_CREATING_KEY_RESP_FROM_DER;
        goto loser;
    }
    numResponses = CMMF_POPODecKeyRespContentGetNumResponses(respContent);
    for (i = 0; i < numResponses; i++) {
        srv = CMMF_POPODecKeyRespContentGetResponse(respContent, i, &curResponse);
        if (srv != SECSuccess) {
            rv = ERROR_RETRIEVING_CLIENT_RESPONSE_TO_CHALLENGE;
            goto loser;
        }
        sprintf(cgiChalVar, "chal%d", i + 1);
        formChalValue = CGITableFindValue(varTable, cgiChalVar);
        if (formChalValue == NULL) {
            rv = REQ_CGI_VAR_NOT_PRESENT;
            missingVar = strdup(cgiChalVar);
            goto loser;
        }
        sscanf(formChalValue, "%ld", &expectedResponse);
        if (expectedResponse != curResponse) {
            rv = ERROR_RETURNED_CHALL_NOT_VALUE_EXPECTED;
            goto loser;
        }
    }
    nickname = CGITableFindValue(varTable, "nickname");
    if (nickname == NULL) {
        rv = REQ_CGI_VAR_NOT_PRESENT;
        missingVar = "nickname";
        goto loser;
    }
    spitOutCMMFResponse(nickname, certRepContent);
loser:
    if (respContent != NULL) {
        CMMF_DestroyPOPODecKeyRespContent(respContent);
    }
    return rv;
}

int
main()
{
    char *form_output = NULL;
    int form_output_len, form_output_used;
    CGIVarTable varTable = { 0 };
    ErrorCode errNum = 0;
    char *certRepContent;

#ifdef ATTACH_CGI
    /* Put an ifinite loop in here so I can attach to
     * the process after the process is spun off
     */
    {
        int stupid = 1;
        while (stupid)
            ;
    }
#endif

    form_output_used = 0;
    srand(time(NULL));
    while (feof(stdin) == 0) {
        if (form_output == NULL) {
            form_output = PORT_NewArray(char, DEFAULT_ALLOC_SIZE + 1);
            form_output_len = DEFAULT_ALLOC_SIZE;
        } else if ((form_output_used + DEFAULT_ALLOC_SIZE) >= form_output_len) {
            form_output_len += DEFAULT_ALLOC_SIZE;
            form_output = PORT_Realloc(form_output, form_output_len + 1);
        }
        form_output_used += fread(&form_output[form_output_used], sizeof(char),
                                  DEFAULT_ALLOC_SIZE, stdin);
    }
    ParseInputVariables(&varTable, form_output);
    certRepContent = CGITableFindValue(&varTable, "CertRepContent");
    if (certRepContent == NULL) {
        errNum = initNSS(&varTable);
        if (errNum != 0) {
            goto loser;
        }
        errNum = processRequest(&varTable);
    } else {
        errNum = processChallengeResponse(&varTable, certRepContent);
    }
    if (errNum != NO_ERROR) {
        goto loser;
    }
    goto done;
loser:
    dumpErrorMessage(errNum);
done:
    free(form_output);
    return 0;
}
