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

/*
 * pk1sign
 */

#include "nspr.h"
#include "plgetopt.h"
#include "secutil.h"
#include "secpkcs7.h"
#include "cert.h"
#include "certdb.h"
#include "sechash.h" /* for HASH_GetHashObject() */
#include "nss.h"
#include "pk11func.h"
#include "cryptohi.h"
#include "plbase64.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 fread(char *, size_t, size_t, FILE *);
extern int fwrite(char *, size_t, size_t, FILE *);
extern int fprintf(FILE *, char *, ...);
#endif

static secuPWData pwdata = { PW_NONE, 0 };

SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)

SEC_ASN1Template CERTSignatureDataTemplate[] =
    {
      { SEC_ASN1_SEQUENCE,
        0, NULL, sizeof(CERTSignedData) },
      { SEC_ASN1_INLINE,
        offsetof(CERTSignedData, signatureAlgorithm),
        SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
      { SEC_ASN1_BIT_STRING,
        offsetof(CERTSignedData, signature) },
      { 0 }
    };

static void
Usage(char *progName)
{
    fprintf(stderr,
            "Usage:  %s -k keyname [-d keydir] [-i input] [-o output]\n",
            progName);
    fprintf(stderr, "%-20s Nickname of key to use for signature\n",
            "-k keyname");
    fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n",
            "-d keydir");
    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");
    fprintf(stderr, "%-20s Password to the key databse\n", "-p");
    fprintf(stderr, "%-20s password file\n", "-f");
    exit(-1);
}

static int
ExportPublicKey(FILE *outFile, CERTCertificate *cert)
{
    char *data;
    SECKEYPublicKey *publicKey;
    SECItem *item;

    if (!cert)
        return -1;

    publicKey = CERT_ExtractPublicKey(cert);
    if (!publicKey)
        return -1;

    item = SECKEY_EncodeDERSubjectPublicKeyInfo(publicKey);
    SECKEY_DestroyPublicKey(publicKey);
    if (!item)
        return -1;

    data = PL_Base64Encode((const char *)item->data, item->len, NULL);
    SECITEM_FreeItem(item, PR_TRUE);
    if (!data)
        return -1;

    fputs("pubkey:\n", outFile);
    fputs(data, outFile);
    fputs("\n", outFile);
    PR_Free(data);

    return 0;
}

static int
SignFile(FILE *outFile, PRFileDesc *inFile, CERTCertificate *cert)
{
    SECItem data2sign;
    SECStatus rv;
    SECOidTag algID;
    CERTSignedData sd;
    SECKEYPrivateKey *privKey = NULL;
    char *data = NULL;
    PLArenaPool *arena = NULL;
    SECItem *result = NULL;
    int returnValue = 0;

    if (outFile == NULL || inFile == NULL || cert == NULL) {
        return -1;
    }

    /* suck the file in */
    if (SECU_ReadDERFromFile(&data2sign, inFile, PR_FALSE,
                             PR_FALSE) != SECSuccess) {
        return -1;
    }

    privKey = NULL;
    privKey = PK11_FindKeyByAnyCert(cert, NULL);
    if (!privKey) {
        returnValue = -1;
        goto loser;
    }

    algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1);
    if (algID == SEC_OID_UNKNOWN) {
        returnValue = -1;
        goto loser;
    }

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    PORT_Memset(&sd, 0, sizeof(CERTSignedData));

    rv = SEC_SignData(&(sd.signature), data2sign.data, data2sign.len, privKey, algID);
    if (rv != SECSuccess) {
        fprintf(stderr, "Could not sign.\n");
        returnValue = -1;
        goto loser;
    }
    sd.signature.len = sd.signature.len << 3;

    rv = SECOID_SetAlgorithmID(arena, &sd.signatureAlgorithm, algID, 0);
    if (rv != SECSuccess) {
        fprintf(stderr, "Could not set alg id.\n");
        returnValue = -1;
        goto loser;
    }

    result = SEC_ASN1EncodeItem(arena, NULL, &sd, CERTSignatureDataTemplate);
    SECITEM_FreeItem(&(sd.signature), PR_FALSE);

    if (!result) {
        fprintf(stderr, "Could not encode.\n");
        returnValue = -1;
        goto loser;
    }

    data = PL_Base64Encode((const char *)result->data, result->len, NULL);
    if (!data) {
        returnValue = -1;
        goto loser;
    }

    fputs("signature:\n", outFile);
    fputs(data, outFile);
    fputs("\n", outFile);
    ExportPublicKey(outFile, cert);

loser:
    if (privKey) {
        SECKEY_DestroyPrivateKey(privKey);
    }
    if (data) {
        PR_Free(data);
    }
    PORT_FreeArena(arena, PR_FALSE);

    return returnValue;
}

int
main(int argc, char **argv)
{
    char *progName;
    FILE *outFile;
    PRFileDesc *inFile;
    char *keyName = NULL;
    CERTCertDBHandle *certHandle;
    CERTCertificate *cert = NULL;
    PLOptState *optstate;
    PLOptStatus status;
    SECStatus rv;

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

    inFile = NULL;
    outFile = NULL;
    keyName = NULL;

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

            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);
                    return -1;
                }
                break;

            case 'k':
                keyName = strdup(optstate->value);
                break;

            case 'o':
                outFile = fopen(optstate->value, "wb");
                if (!outFile) {
                    fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
                            progName, optstate->value);
                    return -1;
                }
                break;
            case 'p':
                pwdata.source = PW_PLAINTEXT;
                pwdata.data = strdup(optstate->value);
                break;

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

    if (!keyName)
        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);
        goto loser;
    }

    PK11_SetPasswordFunc(SECU_GetModulePassword);

    /* open cert database */
    certHandle = CERT_GetDefaultCertDB();
    if (certHandle == NULL) {
        rv = SECFailure;
        goto loser;
    }

    /* find cert */
    cert = CERT_FindCertByNickname(certHandle, keyName);
    if (cert == NULL) {
        SECU_PrintError(progName,
                        "the corresponding cert for key \"%s\" does not exist",
                        keyName);
        rv = SECFailure;
        goto loser;
    }

    if (SignFile(outFile, inFile, cert)) {
        SECU_PrintError(progName, "problem signing data");
        rv = SECFailure;
        goto loser;
    }

loser:
    if (pwdata.data) {
        PORT_Free(pwdata.data);
    }
    if (keyName) {
        PORT_Free(keyName);
    }
    if (cert) {
        CERT_DestroyCertificate(cert);
    }
    if (inFile && inFile != PR_STDIN) {
        PR_Close(inFile);
    }
    if (outFile && outFile != stdout) {
        fclose(outFile);
    }
    if (NSS_Shutdown() != SECSuccess) {
        SECU_PrintError(progName, "NSS shutdown:");
        exit(1);
    }

    return (rv != SECSuccess);
}
