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

SEC_ASN1_MKSUB(SEC_AnyTemplate)
SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate)

typedef struct ContentInfoStr ContentInfo;
typedef struct DegenerateSignedDataStr DegenerateSignedData;

struct ContentInfoStr {
    SECOidTag contentTypeTag; /* local; not part of encoding */
    SECItem contentType;
    union {
        SECItem *data;
        DegenerateSignedData *signedData;
    } content;
};

struct DegenerateSignedDataStr {
    SECItem version;
    SECItem **digestAlgorithms;
    ContentInfo contentInfo;
    SECItem **certificates;
    SECItem **crls;
    SECItem **signerInfos;
};

static const SEC_ASN1Template *
choose_content_template(void *src_or_dest, PRBool encoding);

static const SEC_ASN1TemplateChooserPtr template_chooser = choose_content_template;

static const SEC_ASN1Template ContentInfoTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(ContentInfo) },
    { SEC_ASN1_OBJECT_ID,
      offsetof(ContentInfo, contentType) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_DYNAMIC |
          SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
      offsetof(ContentInfo, content),
      &template_chooser },
    { 0 }
};

static const SEC_ASN1Template DegenerateSignedDataTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(DegenerateSignedData) },
    { SEC_ASN1_INTEGER,
      offsetof(DegenerateSignedData, version) },
    { SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
      offsetof(DegenerateSignedData, digestAlgorithms),
      SEC_ASN1_SUB(SEC_AnyTemplate) },
    { SEC_ASN1_INLINE,
      offsetof(DegenerateSignedData, contentInfo),
      ContentInfoTemplate },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
          SEC_ASN1_XTRN | 0,
      offsetof(DegenerateSignedData, certificates),
      SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
          SEC_ASN1_XTRN | 1,
      offsetof(DegenerateSignedData, crls),
      SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
    { SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
      offsetof(DegenerateSignedData, signerInfos),
      SEC_ASN1_SUB(SEC_AnyTemplate) },
    { 0 }
};

static const SEC_ASN1Template PointerToDegenerateSignedDataTemplate[] = {
    { SEC_ASN1_POINTER, 0, DegenerateSignedDataTemplate }
};

static SECOidTag
GetContentTypeTag(ContentInfo *cinfo)
{
    if (cinfo->contentTypeTag == SEC_OID_UNKNOWN)
        cinfo->contentTypeTag = SECOID_FindOIDTag(&cinfo->contentType);
    return cinfo->contentTypeTag;
}

static const SEC_ASN1Template *
choose_content_template(void *src_or_dest, PRBool encoding)
{
    const SEC_ASN1Template *theTemplate;
    ContentInfo *cinfo;
    SECOidTag kind;

    PORT_Assert(src_or_dest != NULL);
    if (src_or_dest == NULL)
        return NULL;

    cinfo = (ContentInfo *)src_or_dest;
    kind = GetContentTypeTag(cinfo);
    switch (kind) {
        default:
            theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
            break;
        case SEC_OID_PKCS7_DATA:
            theTemplate = SEC_ASN1_GET(SEC_PointerToOctetStringTemplate);
            break;
        case SEC_OID_PKCS7_SIGNED_DATA:
            theTemplate = PointerToDegenerateSignedDataTemplate;
            break;
    }
    return theTemplate;
}

static SECStatus
SEC_ReadPKCS7Certs(SECItem *pkcs7Item, CERTImportCertificateFunc f, void *arg)
{
    ContentInfo contentInfo;
    SECStatus rv = SECFailure;
    SECItem **certs;
    int count;
    PLArenaPool *arena;

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

    PORT_Memset(&contentInfo, 0, sizeof(contentInfo));
    if (SEC_ASN1DecodeItem(arena, &contentInfo, ContentInfoTemplate,
                           pkcs7Item) != SECSuccess) {
        goto done;
    }

    if (GetContentTypeTag(&contentInfo) != SEC_OID_PKCS7_SIGNED_DATA) {
        goto done;
    }

    if (contentInfo.content.signedData == NULL) {
        PORT_SetError(SEC_ERROR_BAD_DER);
        goto done;
    }

    rv = SECSuccess;

    certs = contentInfo.content.signedData->certificates;
    if (certs) {
        count = 0;

        while (*certs) {
            count++;
            certs++;
        }
        rv = (*f)(arg, contentInfo.content.signedData->certificates, count);
    }

done:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return rv;
}

const SEC_ASN1Template SEC_CertSequenceTemplate[] = {
    { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 0, SEC_ASN1_SUB(SEC_AnyTemplate) }
};

static SECStatus
SEC_ReadCertSequence(SECItem *certsItem, CERTImportCertificateFunc f, void *arg)
{
    SECStatus rv = SECFailure;
    SECItem **certs;
    int count;
    SECItem **rawCerts = NULL;
    PLArenaPool *arena;
    ContentInfo contentInfo;

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

    PORT_Memset(&contentInfo, 0, sizeof(contentInfo));
    if (SEC_ASN1DecodeItem(arena, &contentInfo, ContentInfoTemplate,
                           certsItem) != SECSuccess) {
        goto done;
    }

    if (GetContentTypeTag(&contentInfo) != SEC_OID_NS_TYPE_CERT_SEQUENCE) {
        goto done;
    }

    if (SEC_QuickDERDecodeItem(arena, &rawCerts, SEC_CertSequenceTemplate,
                               contentInfo.content.data) != SECSuccess) {
        goto done;
    }

    rv = SECSuccess;

    certs = rawCerts;
    if (certs) {
        count = 0;

        while (*certs) {
            count++;
            certs++;
        }
        rv = (*f)(arg, rawCerts, count);
    }

done:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return rv;
}

CERTCertificate *
CERT_ConvertAndDecodeCertificate(char *certstr)
{
    CERTCertificate *cert;
    SECStatus rv;
    SECItem der;

    rv = ATOB_ConvertAsciiToItem(&der, certstr);
    if (rv != SECSuccess)
        return NULL;

    cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
                                   &der, NULL, PR_FALSE, PR_TRUE);

    PORT_Free(der.data);
    return cert;
}

static const char NS_CERT_HEADER[] = "-----BEGIN CERTIFICATE-----";
static const char NS_CERT_TRAILER[] = "-----END CERTIFICATE-----";
#define NS_CERT_HEADER_LEN ((sizeof NS_CERT_HEADER) - 1)
#define NS_CERT_TRAILER_LEN ((sizeof NS_CERT_TRAILER) - 1)

/*
 * read an old style ascii or binary certificate chain
 */
SECStatus
CERT_DecodeCertPackage(char *certbuf,
                       int certlen,
                       CERTImportCertificateFunc f,
                       void *arg)
{
    unsigned char *cp;
    unsigned char *bincert = NULL;
    char *ascCert = NULL;
    SECStatus rv;

    if (certbuf == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return (SECFailure);
    }
    /*
     * Make sure certlen is long enough to handle the longest possible
     * reference in the code below:
     * 0x30 0x84 l1 l2 l3 l4  +
     *                       tag 9 o1 o2 o3 o4 o5 o6 o7 o8 o9
     * where 9 is the longest length of the expected oids we are testing.
     *   6 + 11 = 17. 17 bytes is clearly too small to code any kind of
     *  certificate (a 128 bit ECC certificate contains at least an 8 byte
     * key and a 16 byte signature, plus coding overhead). Typically a cert
     * is much larger. So it's safe to require certlen to be at least 17
     * bytes.
     */
    if (certlen < 17) {
        PORT_SetError(SEC_ERROR_INPUT_LEN);
        return (SECFailure);
    }

    cp = (unsigned char *)certbuf;

    /* is a DER encoded certificate of some type? */
    if ((*cp & 0x1f) == SEC_ASN1_SEQUENCE) {
        SECItem certitem;
        SECItem *pcertitem = &certitem;
        PRUint64 seqLen, seqLenLen;

        cp++;

        if (*cp & 0x80) {
            /* Multibyte length */
            seqLenLen = cp[0] & 0x7f;

            switch (seqLenLen) {
                case 4:
                    seqLen = ((unsigned long)cp[1] << 24) |
                             ((unsigned long)cp[2] << 16) | (cp[3] << 8) | cp[4];
                    break;
                case 3:
                    seqLen = ((unsigned long)cp[1] << 16) | (cp[2] << 8) | cp[3];
                    break;
                case 2:
                    seqLen = (cp[1] << 8) | cp[2];
                    break;
                case 1:
                    seqLen = cp[1];
                    break;
                case 0:
                    /* indefinite length */
                    seqLen = 0;
                    break;
                default:
                    goto notder;
            }
            cp += (seqLenLen + 1);

        } else {
            seqLenLen = 0;
            seqLen = *cp;
            cp++;
        }

        /* check entire length if definite length */
        if (seqLen || seqLenLen) {
            if (certlen != (seqLen + seqLenLen + 2L)) {
                if (certlen > (seqLen + seqLenLen + 2L))
                    PORT_SetError(SEC_ERROR_EXTRA_INPUT);
                else
                    PORT_SetError(SEC_ERROR_INPUT_LEN);
                goto notder;
            }
        }

        /* check the type oid */
        if (cp[0] == SEC_ASN1_OBJECT_ID) {
            SECOidData *oiddata;
            SECItem oiditem;
            /* XXX - assume DER encoding of OID len!! */
            oiditem.len = cp[1];
            /* if we add an oid below that is longer than 9 bytes, then we
             * need to change the certlen check at the top of the function
             * to prevent a buffer overflow
             */
            if (oiditem.len > 9) {
                PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID);
                return (SECFailure);
            }
            oiditem.data = (unsigned char *)&cp[2];
            oiddata = SECOID_FindOID(&oiditem);
            if (oiddata == NULL) {
                return (SECFailure);
            }

            certitem.data = (unsigned char *)certbuf;
            certitem.len = certlen;

            switch (oiddata->offset) {
                case SEC_OID_PKCS7_SIGNED_DATA:
                    /* oid: 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02 */
                    return (SEC_ReadPKCS7Certs(&certitem, f, arg));
                    break;
                case SEC_OID_NS_TYPE_CERT_SEQUENCE:
                    /* oid: 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x02, 0x05 */
                    return (SEC_ReadCertSequence(&certitem, f, arg));
                    break;
                default:
                    break;
            }

        } else {
            /* it had better be a certificate by now!! */
            certitem.data = (unsigned char *)certbuf;
            certitem.len = certlen;

            rv = (*f)(arg, &pcertitem, 1);
            return (rv);
        }
    }

/* now look for a netscape base64 ascii encoded cert */
notder : {
    unsigned char *certbegin = NULL;
    unsigned char *certend = NULL;
    char *pc;
    int cl;

    /* Convert the ASCII data into a nul-terminated string */
    ascCert = (char *)PORT_Alloc(certlen + 1);
    if (!ascCert) {
        rv = SECFailure;
        goto loser;
    }

    PORT_Memcpy(ascCert, certbuf, certlen);
    ascCert[certlen] = '\0';

    pc = PORT_Strchr(ascCert, '\n'); /* find an EOL */
    if (!pc) {                       /* maybe this is a MAC file */
        pc = ascCert;
        while (*pc && NULL != (pc = PORT_Strchr(pc, '\r'))) {
            *pc++ = '\n';
        }
    }

    cp = (unsigned char *)ascCert;
    cl = certlen;

    /* find the beginning marker */
    while (cl > NS_CERT_HEADER_LEN) {
        int found = 0;
        if (!PORT_Strncasecmp((char *)cp, NS_CERT_HEADER,
                              NS_CERT_HEADER_LEN)) {
            cl -= NS_CERT_HEADER_LEN;
            cp += NS_CERT_HEADER_LEN;
            found = 1;
        }

        /* skip to next eol */
        while (cl && (*cp != '\n')) {
            cp++;
            cl--;
        }

        /* skip all blank lines */
        while (cl && (*cp == '\n' || *cp == '\r')) {
            cp++;
            cl--;
        }
        if (cl && found) {
            certbegin = cp;
            break;
        }
    }

    if (certbegin) {
        /* find the ending marker */
        while (cl >= NS_CERT_TRAILER_LEN) {
            if (!PORT_Strncasecmp((char *)cp, NS_CERT_TRAILER,
                                  NS_CERT_TRAILER_LEN)) {
                certend = cp;
                break;
            }

            /* skip to next eol */
            while (cl && (*cp != '\n')) {
                cp++;
                cl--;
            }

            /* skip all blank lines */
            while (cl && (*cp == '\n' || *cp == '\r')) {
                cp++;
                cl--;
            }
        }
    }

    if (certbegin && certend) {
        unsigned int binLen;

        *certend = 0;
        /* convert to binary */
        bincert = ATOB_AsciiToData((char *)certbegin, &binLen);
        if (!bincert) {
            rv = SECFailure;
            goto loser;
        }

        /* now recurse to decode the binary */
        rv = CERT_DecodeCertPackage((char *)bincert, binLen, f, arg);

    } else {
        PORT_SetError(SEC_ERROR_BAD_DER);
        rv = SECFailure;
    }
}

loser:

    if (bincert) {
        PORT_Free(bincert);
    }

    if (ascCert) {
        PORT_Free(ascCert);
    }

    return (rv);
}

typedef struct {
    PLArenaPool *arena;
    SECItem cert;
} collect_args;

static SECStatus
collect_certs(void *arg, SECItem **certs, int numcerts)
{
    collect_args *collectArgs = (collect_args *)arg;
    if (!collectArgs || !collectArgs->arena) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if (numcerts < 1 || !certs || !*certs) {
        PORT_SetError(SEC_ERROR_BAD_DER);
        return SECFailure;
    }
    return SECITEM_CopyItem(collectArgs->arena, &collectArgs->cert, *certs);
}

/*
 * read an old style ascii or binary certificate
 */
CERTCertificate *
CERT_DecodeCertFromPackage(char *certbuf, int certlen)
{
    collect_args collectArgs;
    SECStatus rv;
    CERTCertificate *cert = NULL;

    collectArgs.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    rv = CERT_DecodeCertPackage(certbuf, certlen, collect_certs,
                                (void *)&collectArgs);
    if (rv == SECSuccess) {
        cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
                                       &collectArgs.cert, NULL,
                                       PR_FALSE, PR_TRUE);
    }

    PORT_FreeArena(collectArgs.arena, PR_FALSE);

    return (cert);
}
