/* 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 "lowkeyi.h"
#include "secoid.h"
#include "secitem.h"
#include "secder.h"
#include "base64.h"
#include "secasn1.h"
#include "secerr.h"
#include "softoken.h"

SEC_ASN1_MKSUB(SEC_AnyTemplate)
SEC_ASN1_MKSUB(SEC_BitStringTemplate)
SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)

const SEC_ASN1Template nsslowkey_AttributeTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(NSSLOWKEYAttribute) },
    { SEC_ASN1_OBJECT_ID, offsetof(NSSLOWKEYAttribute, attrType) },
    { SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
      offsetof(NSSLOWKEYAttribute, attrValue),
      SEC_ASN1_SUB(SEC_AnyTemplate) },
    { 0 }
};

const SEC_ASN1Template nsslowkey_SetOfAttributeTemplate[] = {
    { SEC_ASN1_SET_OF, 0, nsslowkey_AttributeTemplate },
};
/* ASN1 Templates for new decoder/encoder */
const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) },
    { SEC_ASN1_INTEGER,
      offsetof(NSSLOWKEYPrivateKeyInfo, version) },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
      offsetof(NSSLOWKEYPrivateKeyInfo, algorithm),
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    { SEC_ASN1_OCTET_STRING,
      offsetof(NSSLOWKEYPrivateKeyInfo, privateKey) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
      offsetof(NSSLOWKEYPrivateKeyInfo, attributes),
      nsslowkey_SetOfAttributeTemplate },
    { 0 }
};

const SEC_ASN1Template nsslowkey_SubjectPublicKeyInfoTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYSubjectPublicKeyInfo) },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
      offsetof(NSSLOWKEYSubjectPublicKeyInfo, algorithm),
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    { SEC_ASN1_BIT_STRING,
      offsetof(NSSLOWKEYSubjectPublicKeyInfo, subjectPublicKey) },
    { 0 }
};

const SEC_ASN1Template nsslowkey_RSAPublicKeyTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPublicKey) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey, u.rsa.modulus) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey, u.rsa.publicExponent) },
    { 0 }
};

const SEC_ASN1Template nsslowkey_PQGParamsTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PQGParams) },
    { SEC_ASN1_INTEGER, offsetof(PQGParams, prime) },
    { SEC_ASN1_INTEGER, offsetof(PQGParams, subPrime) },
    { SEC_ASN1_INTEGER, offsetof(PQGParams, base) },
    { 0 }
};

const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.version) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.modulus) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.publicExponent) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.privateExponent) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.prime1) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.prime2) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.exponent1) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.exponent2) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.coefficient) },
    { 0 }
};

const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.dsa.publicValue) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.dsa.privateValue) },
    { 0 }
};

const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[] = {
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.dsa.privateValue) },
};

const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.dh.publicValue) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.dh.privateValue) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.dh.base) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.dh.prime) },
    { 0 }
};

/* NOTE: The SECG specification allows the private key structure
 * to contain curve parameters but recommends that they be stored
 * in the PrivateKeyAlgorithmIdentifier field of the PrivateKeyInfo
 * instead.
 */
const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.ec.version) },
    { SEC_ASN1_OCTET_STRING,
      offsetof(NSSLOWKEYPrivateKey, u.ec.privateValue) },
    /* We only support named curves for which the parameters are
     * encoded as an object ID.
     */
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
          SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
          SEC_ASN1_XTRN | 0,
      offsetof(NSSLOWKEYPrivateKey, u.ec.ecParams.curveOID),
      SEC_ASN1_SUB(SEC_ObjectIDTemplate) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
          SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
          SEC_ASN1_XTRN | 1,
      offsetof(NSSLOWKEYPrivateKey, u.ec.publicValue),
      SEC_ASN1_SUB(SEC_BitStringTemplate) },
    { 0 }
};
/*
 * See bugzilla bug 125359
 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
 * all of the templates above that en/decode into integers must be converted
 * from ASN.1's signed integer type.  This is done by marking either the
 * source or destination (encoding or decoding, respectively) type as
 * siUnsignedInteger.
 */

void
prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
{
    key->u.rsa.modulus.type = siUnsignedInteger;
    key->u.rsa.publicExponent.type = siUnsignedInteger;
    key->u.rsa.privateExponent.type = siUnsignedInteger;
    key->u.rsa.prime1.type = siUnsignedInteger;
    key->u.rsa.prime2.type = siUnsignedInteger;
    key->u.rsa.exponent1.type = siUnsignedInteger;
    key->u.rsa.exponent2.type = siUnsignedInteger;
    key->u.rsa.coefficient.type = siUnsignedInteger;
}

void
prepare_low_rsa_pub_key_for_asn1(NSSLOWKEYPublicKey *key)
{
    key->u.rsa.modulus.type = siUnsignedInteger;
    key->u.rsa.publicExponent.type = siUnsignedInteger;
}

void
prepare_low_pqg_params_for_asn1(PQGParams *params)
{
    params->prime.type = siUnsignedInteger;
    params->subPrime.type = siUnsignedInteger;
    params->base.type = siUnsignedInteger;
}

void
prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
{
    key->u.dsa.publicValue.type = siUnsignedInteger;
    key->u.dsa.privateValue.type = siUnsignedInteger;
    key->u.dsa.params.prime.type = siUnsignedInteger;
    key->u.dsa.params.subPrime.type = siUnsignedInteger;
    key->u.dsa.params.base.type = siUnsignedInteger;
}

void
prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key)
{
    key->u.dsa.privateValue.type = siUnsignedInteger;
}

void
prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
{
    key->u.dh.prime.type = siUnsignedInteger;
    key->u.dh.base.type = siUnsignedInteger;
    key->u.dh.publicValue.type = siUnsignedInteger;
    key->u.dh.privateValue.type = siUnsignedInteger;
}

void
prepare_low_ecparams_for_asn1(ECParams *params)
{
    params->DEREncoding.type = siUnsignedInteger;
    params->curveOID.type = siUnsignedInteger;
}

void
prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
{
    key->u.ec.version.type = siUnsignedInteger;
    key->u.ec.ecParams.DEREncoding.type = siUnsignedInteger;
    key->u.ec.ecParams.curveOID.type = siUnsignedInteger;
    key->u.ec.privateValue.type = siUnsignedInteger;
    key->u.ec.publicValue.type = siUnsignedInteger;
}

void
nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk)
{
    if (privk && privk->arena) {
        PORT_FreeArena(privk->arena, PR_TRUE);
    }
}

void
nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk)
{
    if (pubk && pubk->arena) {
        PORT_FreeArena(pubk->arena, PR_FALSE);
    }
}
unsigned
nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubk)
{
    unsigned char b0;

    /* interpret modulus length as key strength... in
     * fortezza that's the public key length */

    switch (pubk->keyType) {
        case NSSLOWKEYRSAKey:
            b0 = pubk->u.rsa.modulus.data[0];
            return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1;
        default:
            break;
    }
    return 0;
}

unsigned
nsslowkey_PrivateModulusLen(NSSLOWKEYPrivateKey *privk)
{

    unsigned char b0;

    switch (privk->keyType) {
        case NSSLOWKEYRSAKey:
            b0 = privk->u.rsa.modulus.data[0];
            return b0 ? privk->u.rsa.modulus.len : privk->u.rsa.modulus.len - 1;
        default:
            break;
    }
    return 0;
}

NSSLOWKEYPublicKey *
nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
{
    NSSLOWKEYPublicKey *pubk;
    PLArenaPool *arena;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    switch (privk->keyType) {
        case NSSLOWKEYRSAKey:
        case NSSLOWKEYNullKey:
            pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
                                                          sizeof(NSSLOWKEYPublicKey));
            if (pubk != NULL) {
                SECStatus rv;

                pubk->arena = arena;
                pubk->keyType = privk->keyType;
                if (privk->keyType == NSSLOWKEYNullKey)
                    return pubk;
                rv = SECITEM_CopyItem(arena, &pubk->u.rsa.modulus,
                                      &privk->u.rsa.modulus);
                if (rv == SECSuccess) {
                    rv = SECITEM_CopyItem(arena, &pubk->u.rsa.publicExponent,
                                          &privk->u.rsa.publicExponent);
                    if (rv == SECSuccess)
                        return pubk;
                }
            } else {
                PORT_SetError(SEC_ERROR_NO_MEMORY);
            }
            break;
        case NSSLOWKEYDSAKey:
            pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
                                                          sizeof(NSSLOWKEYPublicKey));
            if (pubk != NULL) {
                SECStatus rv;

                pubk->arena = arena;
                pubk->keyType = privk->keyType;
                rv = SECITEM_CopyItem(arena, &pubk->u.dsa.publicValue,
                                      &privk->u.dsa.publicValue);
                if (rv != SECSuccess)
                    break;
                rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime,
                                      &privk->u.dsa.params.prime);
                if (rv != SECSuccess)
                    break;
                rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime,
                                      &privk->u.dsa.params.subPrime);
                if (rv != SECSuccess)
                    break;
                rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base,
                                      &privk->u.dsa.params.base);
                if (rv == SECSuccess)
                    return pubk;
            }
            break;
        case NSSLOWKEYDHKey:
            pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
                                                          sizeof(NSSLOWKEYPublicKey));
            if (pubk != NULL) {
                SECStatus rv;

                pubk->arena = arena;
                pubk->keyType = privk->keyType;
                rv = SECITEM_CopyItem(arena, &pubk->u.dh.publicValue,
                                      &privk->u.dh.publicValue);
                if (rv != SECSuccess)
                    break;
                rv = SECITEM_CopyItem(arena, &pubk->u.dh.prime,
                                      &privk->u.dh.prime);
                if (rv != SECSuccess)
                    break;
                rv = SECITEM_CopyItem(arena, &pubk->u.dh.base,
                                      &privk->u.dh.base);
                if (rv == SECSuccess)
                    return pubk;
            }
            break;
        case NSSLOWKEYECKey:
            pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
                                                          sizeof(NSSLOWKEYPublicKey));
            if (pubk != NULL) {
                SECStatus rv;

                pubk->arena = arena;
                pubk->keyType = privk->keyType;
                rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue,
                                      &privk->u.ec.publicValue);
                if (rv != SECSuccess)
                    break;
                pubk->u.ec.ecParams.arena = arena;
                /* Copy the rest of the params */
                rv = EC_CopyParams(arena, &(pubk->u.ec.ecParams),
                                   &(privk->u.ec.ecParams));
                if (rv == SECSuccess)
                    return pubk;
            }
            break;
        /* No Fortezza in Low Key implementations (Fortezza keys aren't
         * stored in our data base */
        default:
            break;
    }

    PORT_FreeArena(arena, PR_FALSE);
    return NULL;
}

NSSLOWKEYPrivateKey *
nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey)
{
    NSSLOWKEYPrivateKey *returnKey = NULL;
    SECStatus rv = SECFailure;
    PLArenaPool *poolp;

    if (!privKey) {
        return NULL;
    }

    poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!poolp) {
        return NULL;
    }

    returnKey = (NSSLOWKEYPrivateKey *)PORT_ArenaZAlloc(poolp, sizeof(NSSLOWKEYPrivateKey));
    if (!returnKey) {
        rv = SECFailure;
        goto loser;
    }

    returnKey->keyType = privKey->keyType;
    returnKey->arena = poolp;

    switch (privKey->keyType) {
        case NSSLOWKEYRSAKey:
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.modulus),
                                  &(privKey->u.rsa.modulus));
            if (rv != SECSuccess)
                break;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.version),
                                  &(privKey->u.rsa.version));
            if (rv != SECSuccess)
                break;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.publicExponent),
                                  &(privKey->u.rsa.publicExponent));
            if (rv != SECSuccess)
                break;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.privateExponent),
                                  &(privKey->u.rsa.privateExponent));
            if (rv != SECSuccess)
                break;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime1),
                                  &(privKey->u.rsa.prime1));
            if (rv != SECSuccess)
                break;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime2),
                                  &(privKey->u.rsa.prime2));
            if (rv != SECSuccess)
                break;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent1),
                                  &(privKey->u.rsa.exponent1));
            if (rv != SECSuccess)
                break;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent2),
                                  &(privKey->u.rsa.exponent2));
            if (rv != SECSuccess)
                break;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.coefficient),
                                  &(privKey->u.rsa.coefficient));
            if (rv != SECSuccess)
                break;
            break;
        case NSSLOWKEYDSAKey:
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.publicValue),
                                  &(privKey->u.dsa.publicValue));
            if (rv != SECSuccess)
                break;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.privateValue),
                                  &(privKey->u.dsa.privateValue));
            if (rv != SECSuccess)
                break;
            returnKey->u.dsa.params.arena = poolp;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.prime),
                                  &(privKey->u.dsa.params.prime));
            if (rv != SECSuccess)
                break;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.subPrime),
                                  &(privKey->u.dsa.params.subPrime));
            if (rv != SECSuccess)
                break;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.base),
                                  &(privKey->u.dsa.params.base));
            if (rv != SECSuccess)
                break;
            break;
        case NSSLOWKEYDHKey:
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.publicValue),
                                  &(privKey->u.dh.publicValue));
            if (rv != SECSuccess)
                break;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.privateValue),
                                  &(privKey->u.dh.privateValue));
            if (rv != SECSuccess)
                break;
            returnKey->u.dsa.params.arena = poolp;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.prime),
                                  &(privKey->u.dh.prime));
            if (rv != SECSuccess)
                break;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.base),
                                  &(privKey->u.dh.base));
            if (rv != SECSuccess)
                break;
            break;
        case NSSLOWKEYECKey:
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.version),
                                  &(privKey->u.ec.version));
            if (rv != SECSuccess)
                break;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.publicValue),
                                  &(privKey->u.ec.publicValue));
            if (rv != SECSuccess)
                break;
            rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.privateValue),
                                  &(privKey->u.ec.privateValue));
            if (rv != SECSuccess)
                break;
            returnKey->u.ec.ecParams.arena = poolp;
            /* Copy the rest of the params */
            rv = EC_CopyParams(poolp, &(returnKey->u.ec.ecParams),
                               &(privKey->u.ec.ecParams));
            if (rv != SECSuccess)
                break;
            break;
        default:
            rv = SECFailure;
    }

loser:

    if (rv != SECSuccess) {
        PORT_FreeArena(poolp, PR_TRUE);
        returnKey = NULL;
    }

    return returnKey;
}
