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

/*
 * p7content -- A command to display pkcs7 content.
 */

#include "nspr.h"
#include "secutil.h"
#include "plgetopt.h"
#include "secpkcs7.h"
#include "cert.h"
#include "certdb.h"
#include "nss.h"
#include "pk11pub.h"

#if defined(XP_UNIX)
#include <unistd.h>
#endif

#include <stdio.h>
#include <string.h>

#if (defined(XP_WIN) && !defined(WIN32)) || (defined(__sun) && !defined(SVR4))
extern int fwrite(char *, size_t, size_t, FILE *);
extern int fprintf(FILE *, char *, ...);
#endif

static void
Usage(char *progName)
{
    fprintf(stderr,
            "Usage:  %s [-d dbdir] [-i input] [-o output]\n",
            progName);
    fprintf(stderr,
            "%-20s Key/Cert database directory (default is ~/.netscape)\n",
            "-d dbdir");
    fprintf(stderr, "%-20s Define an input file to use (default is stdin)\n",
            "-i input");
    fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
            "-o output");
    exit(-1);
}

static PRBool saw_content;
static secuPWData pwdata = { PW_NONE, 0 };

static void
PrintBytes(void *arg, const char *buf, unsigned long len)
{
    FILE *out;

    out = arg;
    fwrite(buf, len, 1, out);

    saw_content = PR_TRUE;
}

/*
 * XXX Someday we may want to do real policy stuff here.  This allows
 * anything to be decrypted, which is okay for a test program but does
 * not set an example of how a real client with a real policy would
 * need to do it.
 */
static PRBool
decryption_allowed(SECAlgorithmID *algid, PK11SymKey *key)
{
    return PR_TRUE;
}

int
DecodeAndPrintFile(FILE *out, PRFileDesc *in, char *progName)
{
    SECItem derdata;
    SEC_PKCS7ContentInfo *cinfo = NULL;
    SEC_PKCS7DecoderContext *dcx;

    if (SECU_ReadDERFromFile(&derdata, in, PR_FALSE, PR_FALSE)) {
        SECU_PrintError(progName, "error converting der");
        return -1;
    }

    fprintf(out,
            "Content printed between bars (newline added before second bar):");
    fprintf(out, "\n---------------------------------------------\n");

    saw_content = PR_FALSE;
    dcx = SEC_PKCS7DecoderStart(PrintBytes, out, NULL, &pwdata,
                                NULL, NULL, decryption_allowed);
    if (dcx != NULL) {
#if 0 /* Test that decoder works when data is really streaming in. */
    {
        unsigned long i;
        for (i = 0; i < derdata.len; i++)
        SEC_PKCS7DecoderUpdate(dcx, derdata.data + i, 1);
    }
#else
        SEC_PKCS7DecoderUpdate(dcx, (char *)derdata.data, derdata.len);
#endif
        cinfo = SEC_PKCS7DecoderFinish(dcx);
    }

    fprintf(out, "\n---------------------------------------------\n");

    if (cinfo == NULL)
        return -1;

    fprintf(out, "Content was%s encrypted.\n",
            SEC_PKCS7ContentIsEncrypted(cinfo) ? "" : " not");

    if (SEC_PKCS7ContentIsSigned(cinfo)) {
        char *signer_cname, *signer_ename;
        SECItem *signing_time;

        if (saw_content) {
            fprintf(out, "Signature is ");
            PORT_SetError(0);
            if (SEC_PKCS7VerifySignature(cinfo, certUsageEmailSigner, PR_FALSE))
                fprintf(out, "valid.\n");
            else
                fprintf(out, "invalid (Reason: %s).\n",
                        SECU_Strerror(PORT_GetError()));
        } else {
            fprintf(out,
                    "Content is detached; signature cannot be verified.\n");
        }

        signer_cname = SEC_PKCS7GetSignerCommonName(cinfo);
        if (signer_cname != NULL) {
            fprintf(out, "The signer's common name is %s\n", signer_cname);
            PORT_Free(signer_cname);
        } else {
            fprintf(out, "No signer common name.\n");
        }

        signer_ename = SEC_PKCS7GetSignerEmailAddress(cinfo);
        if (signer_ename != NULL) {
            fprintf(out, "The signer's email address is %s\n", signer_ename);
            PORT_Free(signer_ename);
        } else {
            fprintf(out, "No signer email address.\n");
        }

        signing_time = SEC_PKCS7GetSigningTime(cinfo);
        if (signing_time != NULL) {
            SECU_PrintTimeChoice(out, signing_time, "Signing time", 0);
        } else {
            fprintf(out, "No signing time included.\n");
        }
    } else {
        fprintf(out, "Content was not signed.\n");
    }

    fprintf(out, "There were%s certs or crls included.\n",
            SEC_PKCS7ContainsCertsOrCrls(cinfo) ? "" : " no");

    SECITEM_FreeItem(&derdata, PR_FALSE);
    SEC_PKCS7DestroyContentInfo(cinfo);
    return 0;
}

/*
 * Print the contents of a PKCS7 message, indicating signatures, etc.
 */

int
main(int argc, char **argv)
{
    char *progName;
    FILE *outFile;
    PRFileDesc *inFile;
    PLOptState *optstate;
    PLOptStatus status;
    SECStatus rv;
    int error = 0;

    progName = strrchr(argv[0], '/');
    progName = progName ? progName + 1 : argv[0];

    inFile = NULL;
    outFile = NULL;

    /*
     * Parse command line arguments
     */
    optstate = PL_CreateOptState(argc, argv, "d:i:o:p:f:");
    while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
        switch (optstate->option) {
            case 'd':
                SECU_ConfigDirectory(optstate->value);
                break;

            case 'i':
                inFile = PR_Open(optstate->value, PR_RDONLY, 0);
                if (!inFile) {
                    fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
                            progName, optstate->value);
                    error = -1;
                    goto done;
                }
                break;

            case 'o':
                outFile = fopen(optstate->value, "w");
                if (!outFile) {
                    fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
                            progName, optstate->value);
                    error = -1;
                    goto done;
                }
                break;

            case 'p':
                pwdata.source = PW_PLAINTEXT;
                pwdata.data = PORT_Strdup(optstate->value);
                break;

            case 'f':
                pwdata.source = PW_FROMFILE;
                pwdata.data = PORT_Strdup(optstate->value);
                break;

            default:
                Usage(progName);
                break;
        }
    }
    PL_DestroyOptState(optstate);

    if (status == PL_OPT_BAD)
        Usage(progName);

    if (!inFile)
        inFile = PR_STDIN;
    if (!outFile)
        outFile = stdout;

    /* Call the initialization routines */
    PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
    rv = NSS_Init(SECU_ConfigDirectory(NULL));
    if (rv != SECSuccess) {
        SECU_PrintPRandOSError(progName);
        error = -1;
        goto done;
    }

    PK11_SetPasswordFunc(SECU_GetModulePassword);

    if (DecodeAndPrintFile(outFile, inFile, progName)) {
        SECU_PrintError(progName, "problem decoding data");
        error = -1;
        goto done;
    }

done:
    if (inFile && inFile != PR_STDIN) {
        PR_Close(inFile);
    }
    if (outFile && outFile != stdout) {
        fclose(outFile);
    }

    if (NSS_Shutdown() != SECSuccess) {
        error = -1;
    }

    return error;
}
