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

/*
 * CMS miscellaneous utility functions.
 */

#include "cmslocal.h"

#include "cert.h"
#include "keyhi.h"
#include "secasn1.h"
#include "secitem.h"
#include "secoid.h"
#include "pk11func.h"
#include "secerr.h"
#include "sechash.h"

/*
 * NSS_CMSArray_SortByDER - sort array of objects by objects' DER encoding
 *
 * make sure that the order of the objects guarantees valid DER (which must be
 * in lexigraphically ascending order for a SET OF); if reordering is necessary it
 * will be done in place (in objs).
 */
SECStatus
NSS_CMSArray_SortByDER(void **objs, const SEC_ASN1Template *objtemplate, void **objs2)
{
    PLArenaPool *poolp;
    int num_objs;
    SECItem **enc_objs;
    SECStatus rv = SECFailure;
    int i;

    if (objs == NULL) /* already sorted */
        return SECSuccess;

    num_objs = NSS_CMSArray_Count((void **)objs);
    if (num_objs == 0 || num_objs == 1) /* already sorted. */
        return SECSuccess;

    poolp = PORT_NewArena(1024); /* arena for temporaries */
    if (poolp == NULL)
        return SECFailure; /* no memory; nothing we can do... */

    /*
     * Allocate arrays to hold the individual encodings which we will use
     * for comparisons and the reordered attributes as they are sorted.
     */
    enc_objs = (SECItem **)PORT_ArenaZAlloc(poolp, (num_objs + 1) * sizeof(SECItem *));
    if (enc_objs == NULL)
        goto loser;

    /* DER encode each individual object. */
    for (i = 0; i < num_objs; i++) {
        enc_objs[i] = SEC_ASN1EncodeItem(poolp, NULL, objs[i], objtemplate);
        if (enc_objs[i] == NULL)
            goto loser;
    }
    enc_objs[num_objs] = NULL;

    /* now compare and sort objs by the order of enc_objs */
    NSS_CMSArray_Sort((void **)enc_objs, NSS_CMSUtil_DERCompare, objs, objs2);

    rv = SECSuccess;

loser:
    PORT_FreeArena(poolp, PR_FALSE);
    return rv;
}

/*
 * NSS_CMSUtil_DERCompare - for use with NSS_CMSArray_Sort to
 *  sort arrays of SECItems containing DER
 */
int
NSS_CMSUtil_DERCompare(void *a, void *b)
{
    SECItem *der1 = (SECItem *)a;
    SECItem *der2 = (SECItem *)b;
    unsigned int j;

    /*
     * Find the lowest (lexigraphically) encoding.  One that is
     * shorter than all the rest is known to be "less" because each
     * attribute is of the same type (a SEQUENCE) and so thus the
     * first octet of each is the same, and the second octet is
     * the length (or the length of the length with the high bit
     * set, followed by the length, which also works out to always
     * order the shorter first).  Two (or more) that have the
     * same length need to be compared byte by byte until a mismatch
     * is found.
     */
    if (der1->len != der2->len)
        return (der1->len < der2->len) ? -1 : 1;

    for (j = 0; j < der1->len; j++) {
        if (der1->data[j] == der2->data[j])
            continue;
        return (der1->data[j] < der2->data[j]) ? -1 : 1;
    }
    return 0;
}

/*
 * NSS_CMSAlgArray_GetIndexByAlgID - find a specific algorithm in an array of
 * algorithms.
 *
 * algorithmArray - array of algorithm IDs
 * algid - algorithmid of algorithm to pick
 *
 * Returns:
 *  An integer containing the index of the algorithm in the array or -1 if
 *  algorithm was not found.
 */
int
NSS_CMSAlgArray_GetIndexByAlgID(SECAlgorithmID **algorithmArray, SECAlgorithmID *algid)
{
    int i;

    if (algorithmArray == NULL || algorithmArray[0] == NULL)
        return -1;

    for (i = 0; algorithmArray[i] != NULL; i++) {
        if (SECOID_CompareAlgorithmID(algorithmArray[i], algid) == SECEqual)
            break; /* bingo */
    }

    if (algorithmArray[i] == NULL)
        return -1; /* not found */

    return i;
}

/*
 * NSS_CMSAlgArray_GetIndexByAlgTag - find a specific algorithm in an array of
 * algorithms.
 *
 * algorithmArray - array of algorithm IDs
 * algtag - algorithm tag of algorithm to pick
 *
 * Returns:
 *  An integer containing the index of the algorithm in the array or -1 if
 *  algorithm was not found.
 */
int
NSS_CMSAlgArray_GetIndexByAlgTag(SECAlgorithmID **algorithmArray,
                                 SECOidTag algtag)
{
    SECOidData *algid;
    int i = -1;

    if (algorithmArray == NULL || algorithmArray[0] == NULL)
        return i;

#ifdef ORDER_N_SQUARED
    for (i = 0; algorithmArray[i] != NULL; i++) {
        algid = SECOID_FindOID(&(algorithmArray[i]->algorithm));
        if (algid->offset == algtag)
            break; /* bingo */
    }
#else
    algid = SECOID_FindOIDByTag(algtag);
    if (!algid)
        return i;
    for (i = 0; algorithmArray[i] != NULL; i++) {
        if (SECITEM_ItemsAreEqual(&algorithmArray[i]->algorithm, &algid->oid))
            break; /* bingo */
    }
#endif

    if (algorithmArray[i] == NULL)
        return -1; /* not found */

    return i;
}

/*
 * Map a sign algorithm to a digest algorithm.
 * This is used to handle incorrectly formatted packages sent to us
 * from Windows 2003.
 */
SECOidTag
NSS_CMSUtil_MapSignAlgs(SECOidTag signAlg)
{
    switch (signAlg) {
        case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
            return SEC_OID_MD2;
            break;
        case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
            return SEC_OID_MD5;
            break;
        case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
        case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
        case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
            return SEC_OID_SHA1;
            break;
        case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
        case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
            return SEC_OID_SHA256;
            break;
        case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
        case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
            return SEC_OID_SHA384;
            break;
        case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
        case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
            return SEC_OID_SHA512;
            break;
        default:
            break;
    }
    /* not one of the algtags incorrectly sent to us*/
    return signAlg;
}

const SECHashObject *
NSS_CMSUtil_GetHashObjByAlgID(SECAlgorithmID *algid)
{
    SECOidTag oidTag = SECOID_FindOIDTag(&(algid->algorithm));
    const SECHashObject *digobj = HASH_GetHashObjectByOidTag(oidTag);

    return digobj;
}

const SEC_ASN1Template *
NSS_CMSUtil_GetTemplateByTypeTag(SECOidTag type)
{
    const SEC_ASN1Template *template;
    extern const SEC_ASN1Template NSSCMSSignedDataTemplate[];
    extern const SEC_ASN1Template NSSCMSEnvelopedDataTemplate[];
    extern const SEC_ASN1Template NSSCMSEncryptedDataTemplate[];
    extern const SEC_ASN1Template NSSCMSDigestedDataTemplate[];

    switch (type) {
        case SEC_OID_PKCS7_SIGNED_DATA:
            template = NSSCMSSignedDataTemplate;
            break;
        case SEC_OID_PKCS7_ENVELOPED_DATA:
            template = NSSCMSEnvelopedDataTemplate;
            break;
        case SEC_OID_PKCS7_ENCRYPTED_DATA:
            template = NSSCMSEncryptedDataTemplate;
            break;
        case SEC_OID_PKCS7_DIGESTED_DATA:
            template = NSSCMSDigestedDataTemplate;
            break;
        default:
            template = NSS_CMSType_GetTemplate(type);
            break;
    }
    return template;
}

size_t
NSS_CMSUtil_GetSizeByTypeTag(SECOidTag type)
{
    size_t size;

    switch (type) {
        case SEC_OID_PKCS7_SIGNED_DATA:
            size = sizeof(NSSCMSSignedData);
            break;
        case SEC_OID_PKCS7_ENVELOPED_DATA:
            size = sizeof(NSSCMSEnvelopedData);
            break;
        case SEC_OID_PKCS7_ENCRYPTED_DATA:
            size = sizeof(NSSCMSEncryptedData);
            break;
        case SEC_OID_PKCS7_DIGESTED_DATA:
            size = sizeof(NSSCMSDigestedData);
            break;
        default:
            size = NSS_CMSType_GetContentSize(type);
            break;
    }
    return size;
}

NSSCMSContentInfo *
NSS_CMSContent_GetContentInfo(void *msg, SECOidTag type)
{
    NSSCMSContent c;
    NSSCMSContentInfo *cinfo = NULL;

    if (!msg)
        return cinfo;
    c.pointer = msg;
    switch (type) {
        case SEC_OID_PKCS7_SIGNED_DATA:
            cinfo = &(c.signedData->contentInfo);
            break;
        case SEC_OID_PKCS7_ENVELOPED_DATA:
            cinfo = &(c.envelopedData->contentInfo);
            break;
        case SEC_OID_PKCS7_ENCRYPTED_DATA:
            cinfo = &(c.encryptedData->contentInfo);
            break;
        case SEC_OID_PKCS7_DIGESTED_DATA:
            cinfo = &(c.digestedData->contentInfo);
            break;
        default:
            cinfo = NULL;
            if (NSS_CMSType_IsWrapper(type)) {
                cinfo = &(c.genericData->contentInfo);
            }
    }
    /* We are using a union as a form of 'safe casting'. This
     * syntax confuses cppcheck, so tell it it's OK (and any human
     * who happens along to verify any other scanner warnings) */
    /* cppcheck-suppress returnDanglingLifetime */
    return cinfo;
}

const char *
NSS_CMSUtil_VerificationStatusToString(NSSCMSVerificationStatus vs)
{
    switch (vs) {
        case NSSCMSVS_Unverified:
            return "Unverified";
        case NSSCMSVS_GoodSignature:
            return "GoodSignature";
        case NSSCMSVS_BadSignature:
            return "BadSignature";
        case NSSCMSVS_DigestMismatch:
            return "DigestMismatch";
        case NSSCMSVS_SigningCertNotFound:
            return "SigningCertNotFound";
        case NSSCMSVS_SigningCertNotTrusted:
            return "SigningCertNotTrusted";
        case NSSCMSVS_SignatureAlgorithmUnknown:
            return "SignatureAlgorithmUnknown";
        case NSSCMSVS_SignatureAlgorithmUnsupported:
            return "SignatureAlgorithmUnsupported";
        case NSSCMSVS_MalformedSignature:
            return "MalformedSignature";
        case NSSCMSVS_ProcessingError:
            return "ProcessingError";
        default:
            return "Unknown";
    }
}

SECStatus
NSS_CMSDEREncode(NSSCMSMessage *cmsg, SECItem *input, SECItem *derOut,
                 PLArenaPool *arena)
{
    NSSCMSEncoderContext *ecx;
    SECStatus rv = SECSuccess;
    if (!cmsg || !derOut || !arena) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    ecx = NSS_CMSEncoder_Start(cmsg, 0, 0, derOut, arena, 0, 0, 0, 0, 0, 0);
    if (!ecx) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    if (input) {
        rv = NSS_CMSEncoder_Update(ecx, (const char *)input->data, input->len);
        if (rv) {
            PORT_SetError(SEC_ERROR_BAD_DATA);
        }
    }
    rv |= NSS_CMSEncoder_Finish(ecx);
    if (rv) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
    }
    return rv;
}
