/* 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 "secutil.h"
#include "secmod.h"
#include "cert.h"
#include "secoid.h"
#include "nss.h"
#include "pk11pub.h"
#include "pk11pqg.h"

/* NSPR 2.0 header files */
#include "prinit.h"
#include "prprf.h"
#include "prsystem.h"
#include "prmem.h"
/* Portable layer header files */
#include "plstr.h"

SECOidData *
getCurveFromString(char *curve_name)
{
    SECOidTag tag = SEC_OID_SECG_EC_SECP256R1;

    if (PORT_Strcasecmp(curve_name, "NISTP256") == 0) {
    } else if (PORT_Strcasecmp(curve_name, "NISTP384") == 0) {
        tag = SEC_OID_SECG_EC_SECP384R1;
    } else if (PORT_Strcasecmp(curve_name, "NISTP521") == 0) {
        tag = SEC_OID_SECG_EC_SECP521R1;
    } else if (PORT_Strcasecmp(curve_name, "Curve25519") == 0) {
        tag = SEC_OID_CURVE25519;
    }
    return SECOID_FindOIDByTag(tag);
}

void
dumpItem(const char *label, const SECItem *item)
{
    int i;
    printf("%s = [%d bytes] {", label, item->len);
    for (i = 0; i < item->len; i++) {
        if ((i & 0xf) == 0)
            printf("\n    ");
        else
            printf(", ");
        printf("%02x", item->data[i]);
    }
    printf("};\n");
}

SECStatus
handleEncryptedPrivateImportTest(char *progName, PK11SlotInfo *slot,
                                 char *testname, CK_MECHANISM_TYPE genMech, void *params, void *pwArgs)
{
    SECStatus rv = SECSuccess;
    SECItem privID = { 0 };
    SECItem pubID = { 0 };
    SECItem pubValue = { 0 };
    SECItem pbePwItem = { 0 };
    SECItem nickname = { 0 };
    SECItem token = { 0 };
    SECKEYPublicKey *pubKey = NULL;
    SECKEYPrivateKey *privKey = NULL;
    PK11GenericObject *objs = NULL;
    PK11GenericObject *obj = NULL;
    SECKEYEncryptedPrivateKeyInfo *epki = NULL;
    PRBool keyFound = 0;
    KeyType keyType;

    fprintf(stderr, "Testing %s PrivateKeyImport ***********************\n",
            testname);

    /* generate a temp key */
    privKey = PK11_GenerateKeyPair(slot, genMech, params, &pubKey,
                                   PR_FALSE, PR_TRUE, pwArgs);
    if (privKey == NULL) {
        SECU_PrintError(progName, "PK11_GenerateKeyPair Failed");
        goto cleanup;
    }

    /* wrap the temp key */
    pbePwItem.data = (unsigned char *)"pw";
    pbePwItem.len = 2;
    epki = PK11_ExportEncryptedPrivKeyInfo(slot, SEC_OID_AES_256_CBC,
                                           &pbePwItem, privKey, 1, NULL);
    if (epki == NULL) {
        SECU_PrintError(progName, "PK11_ExportEncryptedPrivKeyInfo Failed");
        goto cleanup;
    }

    /* Save the public value, which we will need on import */
    keyType = pubKey->keyType;
    switch (keyType) {
        case rsaKey:
            SECITEM_CopyItem(NULL, &pubValue, &pubKey->u.rsa.modulus);
            break;
        case dhKey:
            SECITEM_CopyItem(NULL, &pubValue, &pubKey->u.dh.publicValue);
            break;
        case dsaKey:
            SECITEM_CopyItem(NULL, &pubValue, &pubKey->u.dsa.publicValue);
            break;
        case ecKey:
            SECITEM_CopyItem(NULL, &pubValue, &pubKey->u.ec.publicValue);
            break;
        default:
            fprintf(stderr, "Unknown keytype = %d\n", keyType);
            goto cleanup;
    }
    if (pubValue.data == NULL) {
        SECU_PrintError(progName, "Unable to allocate memory");
        goto cleanup;
    }
    dumpItem("pubValue", &pubValue);

    /* when Asymetric keys represent session keys, those session keys are
     * destroyed when we destroy the Asymetric key representations */
    SECKEY_DestroyPublicKey(pubKey);
    pubKey = NULL;
    SECKEY_DestroyPrivateKey(privKey);
    privKey = NULL;

    /* unwrap the temp key as a perm */
    nickname.data = (unsigned char *)"testKey";
    nickname.len = sizeof("testKey");
    rv = PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(
        slot, epki, &pbePwItem, &nickname, &pubValue,
        PR_TRUE, PR_TRUE, keyType, 0, &privKey, NULL);
    if (rv != SECSuccess) {
        SECU_PrintError(progName, "PK11_ImportEncryptedPrivateKeyInfo Failed");
        goto cleanup;
    }

    /* verify the public key exists */
    rv = PK11_ReadRawAttribute(PK11_TypePrivKey, privKey, CKA_ID, &privID);
    if (rv != SECSuccess) {
        SECU_PrintError(progName,
                        "Couldn't read CKA_ID from pub key, checking next key");
        goto cleanup;
    }
    dumpItem("privKey CKA_ID", &privID);
    objs = PK11_FindGenericObjects(slot, CKO_PUBLIC_KEY);
    for (obj = objs; obj; obj = PK11_GetNextGenericObject(obj)) {
        rv = PK11_ReadRawAttribute(PK11_TypeGeneric, obj, CKA_ID, &pubID);
        if (rv != SECSuccess) {
            SECU_PrintError(progName,
                            "Couldn't read CKA_ID from object, checking next key");
            continue;
        }
        dumpItem("pubKey CKA_ID", &pubID);
        if (!SECITEM_ItemsAreEqual(&privID, &pubID)) {
            fprintf(stderr,
                    "CKA_ID does not match priv key, checking next key\n");
            SECITEM_FreeItem(&pubID, PR_FALSE);
            continue;
        }
        SECITEM_FreeItem(&pubID, PR_FALSE);
        rv = PK11_ReadRawAttribute(PK11_TypeGeneric, obj, CKA_TOKEN, &token);
        if (rv == SECSuccess) {
            if (token.len == 1) {
                keyFound = token.data[0];
            }
            SECITEM_FreeItem(&token, PR_FALSE);
        }
        if (keyFound) {
            printf("matching public key found\n");
            break;
        }
        printf("Matching key was not a token key, checking next key\n");
    }

cleanup:
    if (objs) {
        PK11_DestroyGenericObjects(objs);
    }
    SECITEM_FreeItem(&pubValue, PR_FALSE);
    SECITEM_FreeItem(&privID, PR_FALSE);
    if (epki && epki->arena) {
        PORT_FreeArena(epki->arena, PR_TRUE);
    }
    SECKEY_DestroyPublicKey(pubKey);
    SECKEY_DestroyPrivateKey(privKey);
    fprintf(stderr, "%s PrivateKeyImport %s ***********************\n",
            testname, keyFound ? "PASSED" : "FAILED");
    return keyFound ? SECSuccess : SECFailure;
}

static const char *const usageInfo[] = {
    "pk11import - test PK11_PrivateKeyImport()",
    "Options:",
    " -d certdir            directory containing cert database",
    " -k keysize            size of the rsa, dh, and dsa key to test (default 1024)",
    " -C ecc_curve          ecc curve (default )",
    " -f pwFile             file to fetch the password from",
    " -p pwString           password",
    " -r                    skip rsa test",
    " -D                    skip dsa test",
    " -h                    skip dh test",
    " -e                    skip ec test",
};
static int nUsageInfo = sizeof(usageInfo) / sizeof(char *);

static void
Usage(char *progName, FILE *outFile)
{
    int i;
    fprintf(outFile, "Usage:  %s [ commands ] options\n", progName);
    for (i = 0; i < nUsageInfo; i++)
        fprintf(outFile, "%s\n", usageInfo[i]);
    exit(-1);
}

enum {
    opt_CertDir,
    opt_KeySize,
    opt_ECCurve,
    opt_PWFile,
    opt_PWString,
    opt_NoRSA,
    opt_NoDSA,
    opt_NoEC,
    opt_NoDH
};

static secuCommandFlag options[] =
    {
      { /* opt_CertDir          */ 'd', PR_TRUE, 0, PR_FALSE },
      { /* opt_KeySize          */ 'k', PR_TRUE, 0, PR_FALSE },
      { /* opt_ECCurve          */ 'C', PR_TRUE, 0, PR_FALSE },
      { /* opt_PWFile           */ 'f', PR_TRUE, 0, PR_FALSE },
      { /* opt_PWString         */ 'p', PR_TRUE, 0, PR_FALSE },
      { /* opt_NORSA            */ 'r', PR_TRUE, 0, PR_FALSE },
      { /* opt_NoDSA            */ 'D', PR_TRUE, 0, PR_FALSE },
      { /* opt_NoDH             */ 'h', PR_TRUE, 0, PR_FALSE },
      { /* opt_NoEC             */ 'e', PR_TRUE, 0, PR_FALSE },
    };

int
main(int argc, char **argv)
{
    char *progName;
    SECStatus rv;
    secuCommand args;
    PK11SlotInfo *slot = NULL;
    PRBool failed = PR_FALSE;
    secuPWData pwArgs = { PW_NONE, 0 };
    PRBool doRSA = PR_TRUE;
    PRBool doDSA = PR_TRUE;
    PRBool doDH = PR_FALSE; /* NSS currently can't export wrapped DH keys */
    PRBool doEC = PR_TRUE;
    PQGParams *pqgParams = NULL;
    int keySize;

    args.numCommands = 0;
    args.numOptions = sizeof(options) / sizeof(secuCommandFlag);
    args.commands = NULL;
    args.options = options;

#ifdef XP_PC
    progName = strrchr(argv[0], '\\');
#else
    progName = strrchr(argv[0], '/');
#endif
    progName = progName ? progName + 1 : argv[0];

    rv = SECU_ParseCommandLine(argc, argv, progName, &args);
    if (SECSuccess != rv) {
        Usage(progName, stderr);
    }

    /*  Set the certdb directory (default is ~/.netscape) */
    rv = NSS_InitReadWrite(SECU_ConfigDirectory(args.options[opt_CertDir].arg));
    if (rv != SECSuccess) {
        SECU_PrintPRandOSError(progName);
        return 255;
    }
    PK11_SetPasswordFunc(SECU_GetModulePassword);

    /* below here, goto cleanup */
    SECU_RegisterDynamicOids();

    /* handle the arguments */
    if (args.options[opt_PWFile].arg) {
        pwArgs.source = PW_FROMFILE;
        pwArgs.data = args.options[opt_PWFile].arg;
    }
    if (args.options[opt_PWString].arg) {
        pwArgs.source = PW_PLAINTEXT;
        pwArgs.data = args.options[opt_PWString].arg;
    }
    if (args.options[opt_NoRSA].activated) {
        doRSA = PR_FALSE;
    }
    if (args.options[opt_NoDSA].activated) {
        doDSA = PR_FALSE;
    }
    if (args.options[opt_NoDH].activated) {
        doDH = PR_FALSE;
    }
    if (args.options[opt_NoEC].activated) {
        doEC = PR_FALSE;
    }

    slot = PK11_GetInternalKeySlot();
    if (slot == NULL) {
        SECU_PrintError(progName, "Couldn't find the internal key slot\n");
        return 255;
    }
    rv = PK11_Authenticate(slot, PR_TRUE, &pwArgs);
    if (rv != SECSuccess) {
        SECU_PrintError(progName, "Failed to log into slot");
        PK11_FreeSlot(slot);
        return 255;
    }

    keySize = 1024;
    if (args.options[opt_KeySize].activated &&
        args.options[opt_KeySize].arg) {
        keySize = atoi(args.options[opt_KeySize].arg);
    }

    if (doDSA || doDH) {
        PQGVerify *pqgVfy;
        rv = PK11_PQG_ParamGenV2(keySize, 0, keySize / 16, &pqgParams, &pqgVfy);
        if (rv == SECSuccess) {
            PK11_PQG_DestroyVerify(pqgVfy);
        } else {
            SECU_PrintError(progName,
                            "PK11_PQG_ParamGenV2 failed, can't test DH or DSA");
            doDSA = doDH = PR_FALSE;
            failed = PR_TRUE;
        }
    }

    if (doRSA) {
        PK11RSAGenParams rsaParams;
        rsaParams.keySizeInBits = keySize;
        rsaParams.pe = 0x010001;
        rv = handleEncryptedPrivateImportTest(progName, slot, "RSA",
                                              CKM_RSA_PKCS_KEY_PAIR_GEN, &rsaParams, &pwArgs);
        if (rv != SECSuccess) {
            fprintf(stderr, "RSA Import Failed!\n");
            failed = PR_TRUE;
        }
    }
    if (doDSA) {
        rv = handleEncryptedPrivateImportTest(progName, slot, "DSA",
                                              CKM_DSA_KEY_PAIR_GEN, pqgParams, &pwArgs);
        if (rv != SECSuccess) {
            fprintf(stderr, "DSA Import Failed!\n");
            failed = PR_TRUE;
        }
    }
    if (doDH) {
        SECKEYDHParams dhParams;
        dhParams.prime = pqgParams->prime;
        dhParams.base = pqgParams->base;
        rv = handleEncryptedPrivateImportTest(progName, slot, "DH",
                                              CKM_DH_PKCS_KEY_PAIR_GEN, &dhParams, &pwArgs);
        if (rv != SECSuccess) {
            fprintf(stderr, "DH Import Failed!\n");
            failed = PR_TRUE;
        }
    }
    if (doEC) {
        SECKEYECParams ecParams;
        SECOidData *curve = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1);
        if (args.options[opt_ECCurve].activated &&
            args.options[opt_ECCurve].arg) {
            curve = getCurveFromString(args.options[opt_ECCurve].arg);
        }
        ecParams.data = PORT_Alloc(curve->oid.len + 2);
        if (ecParams.data == NULL) {
            rv = SECFailure;
            goto ec_failed;
        }
        ecParams.data[0] = SEC_ASN1_OBJECT_ID;
        ecParams.data[1] = (unsigned char)curve->oid.len;
        PORT_Memcpy(&ecParams.data[2], curve->oid.data, curve->oid.len);
        ecParams.len = curve->oid.len + 2;
        rv = handleEncryptedPrivateImportTest(progName, slot, "ECC",
                                              CKM_EC_KEY_PAIR_GEN, &ecParams, &pwArgs);
        PORT_Free(ecParams.data);
    ec_failed:
        if (rv != SECSuccess) {
            fprintf(stderr, "ECC Import Failed!\n");
            failed = PR_TRUE;
        }
    }

    if (pqgParams) {
        PK11_PQG_DestroyParams(pqgParams);
    }

    if (slot) {
        PK11_FreeSlot(slot);
    }

    rv = NSS_Shutdown();
    if (rv != SECSuccess) {
        fprintf(stderr, "Shutdown failed\n");
        SECU_PrintPRandOSError(progName);
        return 255;
    }

    return failed ? 1 : 0;
}
