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

/*
 * Support for various policy related extensions
 */

#include "seccomon.h"
#include "secport.h"
#include "secder.h"
#include "cert.h"
#include "secoid.h"
#include "secasn1.h"
#include "secerr.h"
#include "nspr.h"
#include "secutil.h"

/* This implementation is derived from the one in nss/lib/certdb/policyxtn.c .
** The chief difference is the addition of the OPTIONAL flag to many
** parts.  The idea is to be able to parse and print as much of the
** policy extension as possible, even if some parts are invalid.
**
** If this approach still is unable to decode policy extensions that
** contain invalid parts, then the next approach will be to parse
** the PolicyInfos as a SEQUENCE of ANYs, and then parse each of them
** as PolicyInfos, with the PolicyQualifiers being ANYs, and finally
** parse each of the PolicyQualifiers.
*/

static const SEC_ASN1Template secu_PolicyQualifierTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(CERTPolicyQualifier) },
    { SEC_ASN1_OBJECT_ID,
      offsetof(CERTPolicyQualifier, qualifierID) },
    { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
      offsetof(CERTPolicyQualifier, qualifierValue) },
    { 0 }
};

static const SEC_ASN1Template secu_PolicyInfoTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(CERTPolicyInfo) },
    { SEC_ASN1_OBJECT_ID,
      offsetof(CERTPolicyInfo, policyID) },
    { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_OPTIONAL,
      offsetof(CERTPolicyInfo, policyQualifiers),
      secu_PolicyQualifierTemplate },
    { 0 }
};

static const SEC_ASN1Template secu_CertificatePoliciesTemplate[] = {
    { SEC_ASN1_SEQUENCE_OF,
      offsetof(CERTCertificatePolicies, policyInfos),
      secu_PolicyInfoTemplate, sizeof(CERTCertificatePolicies) }
};

static CERTCertificatePolicies *
secu_DecodeCertificatePoliciesExtension(SECItem *extnValue)
{
    PLArenaPool *arena = NULL;
    SECStatus rv;
    CERTCertificatePolicies *policies;
    CERTPolicyInfo **policyInfos, *policyInfo;
    CERTPolicyQualifier **policyQualifiers, *policyQualifier;
    SECItem newExtnValue;

    /* make a new arena */
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    if (!arena) {
        goto loser;
    }

    /* allocate the certifiate policies structure */
    policies = PORT_ArenaZNew(arena, CERTCertificatePolicies);
    if (policies == NULL) {
        goto loser;
    }

    policies->arena = arena;

    /* copy the DER into the arena, since Quick DER returns data that points
       into the DER input, which may get freed by the caller */
    rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* decode the policy info */
    rv = SEC_QuickDERDecodeItem(arena, policies,
                                secu_CertificatePoliciesTemplate,
                                &newExtnValue);

    if (rv != SECSuccess) {
        goto loser;
    }

    /* initialize the oid tags */
    policyInfos = policies->policyInfos;
    while (policyInfos != NULL && *policyInfos != NULL) {
        policyInfo = *policyInfos;
        policyInfo->oid = SECOID_FindOIDTag(&policyInfo->policyID);
        policyQualifiers = policyInfo->policyQualifiers;
        while (policyQualifiers && *policyQualifiers != NULL) {
            policyQualifier = *policyQualifiers;
            policyQualifier->oid =
                SECOID_FindOIDTag(&policyQualifier->qualifierID);
            policyQualifiers++;
        }
        policyInfos++;
    }

    return (policies);

loser:
    if (arena != NULL) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (NULL);
}

static char *
itemToString(SECItem *item)
{
    char *string;

    string = PORT_ZAlloc(item->len + 1);
    if (string == NULL)
        return NULL;
    PORT_Memcpy(string, item->data, item->len);
    string[item->len] = 0;
    return string;
}

static SECStatus
secu_PrintUserNoticeQualifier(FILE *out, SECItem *qualifierValue,
                              char *msg, int level)
{
    CERTUserNotice *userNotice = NULL;
    if (qualifierValue)
        userNotice = CERT_DecodeUserNotice(qualifierValue);
    if (userNotice) {
        if (userNotice->noticeReference.organization.len != 0) {
            char *string =
                itemToString(&userNotice->noticeReference.organization);
            SECItem **itemList = userNotice->noticeReference.noticeNumbers;

            while (itemList && *itemList) {
                SECU_PrintInteger(out, *itemList, string, level + 1);
                itemList++;
            }
            PORT_Free(string);
        }
        if (userNotice->displayText.len != 0) {
            SECU_PrintString(out, &userNotice->displayText,
                             "Display Text", level + 1);
        }
        CERT_DestroyUserNotice(userNotice);
        return SECSuccess;
    }
    return SECFailure; /* caller will print this value */
}

static SECStatus
secu_PrintPolicyQualifier(FILE *out, CERTPolicyQualifier *policyQualifier,
                          char *msg, int level)
{
    SECStatus rv;
    SECItem *qualifierValue = &policyQualifier->qualifierValue;

    SECU_PrintObjectID(out, &policyQualifier->qualifierID,
                       "Policy Qualifier Name", level);
    if (!qualifierValue->data) {
        SECU_Indent(out, level);
        fprintf(out, "Error: missing qualifier\n");
    } else
        switch (policyQualifier->oid) {
            case SEC_OID_PKIX_USER_NOTICE_QUALIFIER:
                rv = secu_PrintUserNoticeQualifier(out, qualifierValue, msg, level);
                if (SECSuccess == rv)
                    break;
            /* fall through on error */
            case SEC_OID_PKIX_CPS_POINTER_QUALIFIER:
            default:
                SECU_PrintAny(out, qualifierValue, "Policy Qualifier Data", level);
                break;
        }
    return SECSuccess;
}

static SECStatus
secu_PrintPolicyInfo(FILE *out, CERTPolicyInfo *policyInfo, char *msg, int level)
{
    CERTPolicyQualifier **policyQualifiers;

    policyQualifiers = policyInfo->policyQualifiers;
    SECU_PrintObjectID(out, &policyInfo->policyID, "Policy Name", level);

    while (policyQualifiers && *policyQualifiers != NULL) {
        secu_PrintPolicyQualifier(out, *policyQualifiers, "", level + 1);
        policyQualifiers++;
    }
    return SECSuccess;
}

void
SECU_PrintPolicy(FILE *out, SECItem *value, char *msg, int level)
{
    CERTCertificatePolicies *policies = NULL;
    CERTPolicyInfo **policyInfos;

    if (msg) {
        SECU_Indent(out, level);
        fprintf(out, "%s: \n", msg);
        level++;
    }
    policies = secu_DecodeCertificatePoliciesExtension(value);
    if (policies == NULL) {
        SECU_PrintAny(out, value, "Invalid Policy Data", level);
        return;
    }

    policyInfos = policies->policyInfos;
    while (policyInfos && *policyInfos != NULL) {
        secu_PrintPolicyInfo(out, *policyInfos, "", level);
        policyInfos++;
    }

    CERT_DestroyCertificatePoliciesExtension(policies);
}

void
SECU_PrintPrivKeyUsagePeriodExtension(FILE *out, SECItem *value,
                                      char *msg, int level)
{
    CERTPrivKeyUsagePeriod *prd;
    PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    if (!arena) {
        goto loser;
    }
    prd = CERT_DecodePrivKeyUsagePeriodExtension(arena, value);
    if (!prd) {
        goto loser;
    }
    if (prd->notBefore.data) {
        SECU_PrintGeneralizedTime(out, &prd->notBefore, "Not Before", level);
    }
    if (prd->notAfter.data) {
        SECU_PrintGeneralizedTime(out, &prd->notAfter, "Not After ", level);
    }
    if (!prd->notBefore.data && !prd->notAfter.data) {
        SECU_Indent(out, level);
        fprintf(out, "Error: notBefore or notAfter MUST be present.\n");
    loser:
        SECU_PrintAny(out, value, msg, level);
    }
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }
}
