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

SEC_ASN1_MKSUB(SEC_IntegerTemplate)
SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)

const SEC_ASN1Template CERT_DisplayTextTypeTemplate[] = {
    { SEC_ASN1_CHOICE, offsetof(SECItem, type), 0, sizeof(SECItem) },
    { SEC_ASN1_IA5_STRING, 0, 0, siAsciiString },
    { SEC_ASN1_VISIBLE_STRING, 0, 0, siVisibleString },
    { SEC_ASN1_BMP_STRING, 0, 0, siBMPString },
    { SEC_ASN1_UTF8_STRING, 0, 0, siUTF8String },
    { 0 }
};

const SEC_ASN1Template CERT_NoticeReferenceTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNoticeReference) },
    { SEC_ASN1_INLINE, offsetof(CERTNoticeReference, organization),
      CERT_DisplayTextTypeTemplate, 0 },
    { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN,
      offsetof(CERTNoticeReference, noticeNumbers),
      SEC_ASN1_SUB(SEC_IntegerTemplate) },
    { 0 }
};

const SEC_ASN1Template CERT_UserNoticeTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTUserNotice) },
    { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL,
      offsetof(CERTUserNotice, noticeReference), CERT_NoticeReferenceTemplate,
      0 },
    { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL,
      offsetof(CERTUserNotice, displayText), CERT_DisplayTextTypeTemplate, 0 },
    { 0 }
};

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

const SEC_ASN1Template CERT_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),
      CERT_PolicyQualifierTemplate },
    { 0 }
};

const SEC_ASN1Template CERT_CertificatePoliciesTemplate[] = {
    { SEC_ASN1_SEQUENCE_OF, offsetof(CERTCertificatePolicies, policyInfos),
      CERT_PolicyInfoTemplate, sizeof(CERTCertificatePolicies) }
};

const SEC_ASN1Template CERT_PolicyMapTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTPolicyMap) },
    { SEC_ASN1_OBJECT_ID, offsetof(CERTPolicyMap, issuerDomainPolicy) },
    { SEC_ASN1_OBJECT_ID, offsetof(CERTPolicyMap, subjectDomainPolicy) },
    { 0 }
};

const SEC_ASN1Template CERT_PolicyMappingsTemplate[] = {
    { SEC_ASN1_SEQUENCE_OF, offsetof(CERTCertificatePolicyMappings, policyMaps),
      CERT_PolicyMapTemplate, sizeof(CERTPolicyMap) }
};

const SEC_ASN1Template CERT_PolicyConstraintsTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCertificatePolicyConstraints) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
      offsetof(CERTCertificatePolicyConstraints, explicitPolicySkipCerts),
      SEC_ASN1_SUB(SEC_IntegerTemplate) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
      offsetof(CERTCertificatePolicyConstraints, inhibitMappingSkipCerts),
      SEC_ASN1_SUB(SEC_IntegerTemplate) },
    { 0 }
};

const SEC_ASN1Template CERT_InhibitAnyTemplate[] = {
    { SEC_ASN1_INTEGER,
      offsetof(CERTCertificateInhibitAny, inhibitAnySkipCerts), NULL,
      sizeof(CERTCertificateInhibitAny) }
};

static void
breakLines(char *string)
{
    char *tmpstr;
    char *lastspace = NULL;
    int curlen = 0;
    int c;

    tmpstr = string;

    while ((c = *tmpstr) != '\0') {
        switch (c) {
            case ' ':
                lastspace = tmpstr;
                break;
            case '\n':
                lastspace = NULL;
                curlen = 0;
                break;
        }

        if ((curlen >= 55) && (lastspace != NULL)) {
            *lastspace = '\n';
            curlen = (tmpstr - lastspace);
            lastspace = NULL;
        }

        curlen++;
        tmpstr++;
    }

    return;
}

CERTCertificatePolicies *
CERT_DecodeCertificatePoliciesExtension(const 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 certificate policies structure */
    policies = (CERTCertificatePolicies *)PORT_ArenaZAlloc(
        arena, sizeof(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, CERT_CertificatePoliciesTemplate, &newExtnValue);

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

    /* initialize the oid tags */
    policyInfos = policies->policyInfos;
    while (*policyInfos != NULL) {
        policyInfo = *policyInfos;
        policyInfo->oid = SECOID_FindOIDTag(&policyInfo->policyID);
        policyQualifiers = policyInfo->policyQualifiers;
        while (policyQualifiers != NULL && *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);
}

void
CERT_DestroyCertificatePoliciesExtension(CERTCertificatePolicies *policies)
{
    if (policies != NULL) {
        PORT_FreeArena(policies->arena, PR_FALSE);
    }
    return;
}

CERTCertificatePolicyMappings *
CERT_DecodePolicyMappingsExtension(SECItem *extnValue)
{
    PLArenaPool *arena = NULL;
    SECStatus rv;
    CERTCertificatePolicyMappings *mappings;
    SECItem newExtnValue;

    /* make a new arena */
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!arena) {
        goto loser;
    }

    /* allocate the policy mappings structure */
    mappings = (CERTCertificatePolicyMappings *)PORT_ArenaZAlloc(
        arena, sizeof(CERTCertificatePolicyMappings));
    if (mappings == NULL) {
        goto loser;
    }
    mappings->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 mappings */
    rv = SEC_QuickDERDecodeItem(arena, mappings, CERT_PolicyMappingsTemplate,
                                &newExtnValue);
    if (rv != SECSuccess) {
        goto loser;
    }

    return (mappings);

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

    return (NULL);
}

SECStatus
CERT_DestroyPolicyMappingsExtension(CERTCertificatePolicyMappings *mappings)
{
    if (mappings != NULL) {
        PORT_FreeArena(mappings->arena, PR_FALSE);
    }
    return SECSuccess;
}

SECStatus
CERT_DecodePolicyConstraintsExtension(
    CERTCertificatePolicyConstraints *decodedValue, const SECItem *encodedValue)
{
    CERTCertificatePolicyConstraints decodeContext;
    PLArenaPool *arena = NULL;
    SECStatus rv = SECSuccess;

    /* initialize so we can tell when an optional component is omitted */
    PORT_Memset(&decodeContext, 0, sizeof(decodeContext));

    /* make a new arena */
    arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
    if (!arena) {
        return SECFailure;
    }

    do {
        /* decode the policy constraints */
        rv = SEC_QuickDERDecodeItem(arena, &decodeContext,
                                    CERT_PolicyConstraintsTemplate,
                                    encodedValue);

        if (rv != SECSuccess) {
            break;
        }

        if (decodeContext.explicitPolicySkipCerts.len == 0) {
            *(PRInt32 *)decodedValue->explicitPolicySkipCerts.data = -1;
        } else {
            *(PRInt32 *)decodedValue->explicitPolicySkipCerts.data =
                DER_GetInteger(&decodeContext.explicitPolicySkipCerts);
        }

        if (decodeContext.inhibitMappingSkipCerts.len == 0) {
            *(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data = -1;
        } else {
            *(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data =
                DER_GetInteger(&decodeContext.inhibitMappingSkipCerts);
        }

        if ((*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data ==
             PR_INT32_MIN) ||
            (*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data ==
             PR_INT32_MAX) ||
            (*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data ==
             PR_INT32_MIN) ||
            (*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data ==
             PR_INT32_MAX)) {
            rv = SECFailure;
        }

    } while (0);

    PORT_FreeArena(arena, PR_FALSE);
    return (rv);
}

SECStatus
CERT_DecodeInhibitAnyExtension(CERTCertificateInhibitAny *decodedValue,
                               SECItem *encodedValue)
{
    CERTCertificateInhibitAny decodeContext;
    PLArenaPool *arena = NULL;
    SECStatus rv = SECSuccess;

    /* make a new arena */
    arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
    if (!arena) {
        return SECFailure;
    }

    do {

        /* decode the policy mappings */
        decodeContext.inhibitAnySkipCerts.type = siUnsignedInteger;
        rv = SEC_QuickDERDecodeItem(arena, &decodeContext,
                                    CERT_InhibitAnyTemplate, encodedValue);

        if (rv != SECSuccess) {
            break;
        }

        *(PRInt32 *)decodedValue->inhibitAnySkipCerts.data =
            DER_GetInteger(&decodeContext.inhibitAnySkipCerts);

    } while (0);

    PORT_FreeArena(arena, PR_FALSE);
    return (rv);
}

CERTUserNotice *
CERT_DecodeUserNotice(SECItem *noticeItem)
{
    PLArenaPool *arena = NULL;
    SECStatus rv;
    CERTUserNotice *userNotice;
    SECItem newNoticeItem;

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

    if (!arena) {
        goto loser;
    }

    /* allocate the userNotice structure */
    userNotice =
        (CERTUserNotice *)PORT_ArenaZAlloc(arena, sizeof(CERTUserNotice));

    if (userNotice == NULL) {
        goto loser;
    }

    userNotice->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, &newNoticeItem, noticeItem);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* decode the user notice */
    rv = SEC_QuickDERDecodeItem(arena, userNotice, CERT_UserNoticeTemplate,
                                &newNoticeItem);

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

    if (userNotice->derNoticeReference.data != NULL) {

        rv = SEC_QuickDERDecodeItem(arena, &userNotice->noticeReference,
                                    CERT_NoticeReferenceTemplate,
                                    &userNotice->derNoticeReference);
        if (rv == SECFailure) {
            goto loser;
        }
    }

    return (userNotice);

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

    return (NULL);
}

void
CERT_DestroyUserNotice(CERTUserNotice *userNotice)
{
    if (userNotice != NULL) {
        PORT_FreeArena(userNotice->arena, PR_FALSE);
    }
    return;
}

static CERTPolicyStringCallback policyStringCB = NULL;
static void *policyStringCBArg = NULL;

void
CERT_SetCAPolicyStringCallback(CERTPolicyStringCallback cb, void *cbarg)
{
    policyStringCB = cb;
    policyStringCBArg = cbarg;
    return;
}

char *
stringFromUserNotice(SECItem *noticeItem)
{
    SECItem *org;
    unsigned int len, headerlen;
    char *stringbuf;
    CERTUserNotice *userNotice;
    char *policystr;
    char *retstr = NULL;
    SECItem *displayText;
    SECItem **noticeNumbers;
    unsigned int strnum;

    /* decode the user notice */
    userNotice = CERT_DecodeUserNotice(noticeItem);
    if (userNotice == NULL) {
        return (NULL);
    }

    org = &userNotice->noticeReference.organization;
    if ((org->len != 0) && (policyStringCB != NULL)) {
        /* has a noticeReference */

        /* extract the org string */
        len = org->len;
        stringbuf = (char *)PORT_Alloc(len + 1);
        if (stringbuf != NULL) {
            PORT_Memcpy(stringbuf, org->data, len);
            stringbuf[len] = '\0';

            noticeNumbers = userNotice->noticeReference.noticeNumbers;
            while (*noticeNumbers != NULL) {
                /* XXX - only one byte integers right now*/
                strnum = (*noticeNumbers)->data[0];
                policystr =
                    (*policyStringCB)(stringbuf, strnum, policyStringCBArg);
                if (policystr != NULL) {
                    if (retstr != NULL) {
                        retstr = PR_sprintf_append(retstr, "\n%s", policystr);
                    } else {
                        retstr = PR_sprintf_append(retstr, "%s", policystr);
                    }

                    PORT_Free(policystr);
                }

                noticeNumbers++;
            }

            PORT_Free(stringbuf);
        }
    }

    if (retstr == NULL) {
        if (userNotice->displayText.len != 0) {
            displayText = &userNotice->displayText;

            if (displayText->len > 2) {
                if (displayText->data[0] == SEC_ASN1_VISIBLE_STRING) {
                    headerlen = 2;
                    if (displayText->data[1] & 0x80) {
                        /* multibyte length */
                        headerlen += (displayText->data[1] & 0x7f);
                    }

                    len = displayText->len - headerlen;
                    retstr = (char *)PORT_Alloc(len + 1);
                    if (retstr != NULL) {
                        PORT_Memcpy(retstr, &displayText->data[headerlen], len);
                        retstr[len] = '\0';
                    }
                }
            }
        }
    }

    CERT_DestroyUserNotice(userNotice);

    return (retstr);
}

char *
CERT_GetCertCommentString(CERTCertificate *cert)
{
    char *retstring = NULL;
    SECStatus rv;
    SECItem policyItem;
    CERTCertificatePolicies *policies = NULL;
    CERTPolicyInfo **policyInfos;
    CERTPolicyQualifier **policyQualifiers, *qualifier;

    policyItem.data = NULL;

    rv = CERT_FindCertExtension(cert, SEC_OID_X509_CERTIFICATE_POLICIES,
                                &policyItem);
    if (rv != SECSuccess) {
        goto nopolicy;
    }

    policies = CERT_DecodeCertificatePoliciesExtension(&policyItem);
    if (policies == NULL) {
        goto nopolicy;
    }

    policyInfos = policies->policyInfos;
    /* search through policyInfos looking for the verisign policy */
    while (*policyInfos != NULL) {
        if ((*policyInfos)->oid == SEC_OID_VERISIGN_USER_NOTICES) {
            policyQualifiers = (*policyInfos)->policyQualifiers;
            /* search through the policy qualifiers looking for user notice */
            while (policyQualifiers != NULL && *policyQualifiers != NULL) {
                qualifier = *policyQualifiers;
                if (qualifier->oid == SEC_OID_PKIX_USER_NOTICE_QUALIFIER) {
                    retstring =
                        stringFromUserNotice(&qualifier->qualifierValue);
                    break;
                }

                policyQualifiers++;
            }
            break;
        }
        policyInfos++;
    }

nopolicy:
    if (policyItem.data != NULL) {
        PORT_Free(policyItem.data);
    }

    if (policies != NULL) {
        CERT_DestroyCertificatePoliciesExtension(policies);
    }

    if (retstring == NULL) {
        retstring =
            CERT_FindNSStringExtension(cert, SEC_OID_NS_CERT_EXT_COMMENT);
    }

    if (retstring != NULL) {
        breakLines(retstring);
    }

    return (retstring);
}

const SEC_ASN1Template CERT_OidSeqTemplate[] = {
    { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, offsetof(CERTOidSequence, oids),
      SEC_ASN1_SUB(SEC_ObjectIDTemplate) }
};

CERTOidSequence *
CERT_DecodeOidSequence(const SECItem *seqItem)
{
    PLArenaPool *arena = NULL;
    SECStatus rv;
    CERTOidSequence *oidSeq;
    SECItem newSeqItem;

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

    if (!arena) {
        goto loser;
    }

    /* allocate the userNotice structure */
    oidSeq =
        (CERTOidSequence *)PORT_ArenaZAlloc(arena, sizeof(CERTOidSequence));

    if (oidSeq == NULL) {
        goto loser;
    }

    oidSeq->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, &newSeqItem, seqItem);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* decode the user notice */
    rv =
        SEC_QuickDERDecodeItem(arena, oidSeq, CERT_OidSeqTemplate, &newSeqItem);

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

    return (oidSeq);

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

void
CERT_DestroyOidSequence(CERTOidSequence *oidSeq)
{
    if (oidSeq != NULL) {
        PORT_FreeArena(oidSeq->arena, PR_FALSE);
    }
    return;
}

PRBool
CERT_GovtApprovedBitSet(CERTCertificate *cert)
{
    SECStatus rv;
    SECItem extItem;
    CERTOidSequence *oidSeq = NULL;
    PRBool ret;
    SECItem **oids;
    SECItem *oid;
    SECOidTag oidTag;

    extItem.data = NULL;
    rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, &extItem);
    if (rv != SECSuccess) {
        goto loser;
    }

    oidSeq = CERT_DecodeOidSequence(&extItem);
    if (oidSeq == NULL) {
        goto loser;
    }

    oids = oidSeq->oids;
    while (oids != NULL && *oids != NULL) {
        oid = *oids;

        oidTag = SECOID_FindOIDTag(oid);

        if (oidTag == SEC_OID_NS_KEY_USAGE_GOVT_APPROVED) {
            goto success;
        }

        oids++;
    }

loser:
    ret = PR_FALSE;
    goto done;
success:
    ret = PR_TRUE;
done:
    if (oidSeq != NULL) {
        CERT_DestroyOidSequence(oidSeq);
    }
    if (extItem.data != NULL) {
        PORT_Free(extItem.data);
    }
    return (ret);
}

SECStatus
CERT_EncodePolicyConstraintsExtension(PLArenaPool *arena,
                                      CERTCertificatePolicyConstraints *constr,
                                      SECItem *dest)
{
    SECStatus rv = SECSuccess;

    PORT_Assert(constr != NULL && dest != NULL);
    if (constr == NULL || dest == NULL) {
        return SECFailure;
    }

    if (SEC_ASN1EncodeItem(arena, dest, constr,
                           CERT_PolicyConstraintsTemplate) == NULL) {
        rv = SECFailure;
    }
    return (rv);
}

SECStatus
CERT_EncodePolicyMappingExtension(PLArenaPool *arena,
                                  CERTCertificatePolicyMappings *mapping,
                                  SECItem *dest)
{
    SECStatus rv = SECSuccess;

    PORT_Assert(mapping != NULL && dest != NULL);
    if (mapping == NULL || dest == NULL) {
        return SECFailure;
    }

    if (SEC_ASN1EncodeItem(arena, dest, mapping, CERT_PolicyMappingsTemplate) ==
        NULL) {
        rv = SECFailure;
    }
    return (rv);
}

SECStatus
CERT_EncodeCertPoliciesExtension(PLArenaPool *arena, CERTPolicyInfo **info,
                                 SECItem *dest)
{
    SECStatus rv = SECSuccess;

    PORT_Assert(info != NULL && dest != NULL);
    if (info == NULL || dest == NULL) {
        return SECFailure;
    }

    if (SEC_ASN1EncodeItem(arena, dest, info,
                           CERT_CertificatePoliciesTemplate) == NULL) {
        rv = SECFailure;
    }
    return (rv);
}

SECStatus
CERT_EncodeUserNotice(PLArenaPool *arena, CERTUserNotice *notice, SECItem *dest)
{
    SECStatus rv = SECSuccess;

    PORT_Assert(notice != NULL && dest != NULL);
    if (notice == NULL || dest == NULL) {
        return SECFailure;
    }

    if (SEC_ASN1EncodeItem(arena, dest, notice, CERT_UserNoticeTemplate) ==
        NULL) {
        rv = SECFailure;
    }

    return (rv);
}

SECStatus
CERT_EncodeNoticeReference(PLArenaPool *arena, CERTNoticeReference *reference,
                           SECItem *dest)
{
    SECStatus rv = SECSuccess;

    PORT_Assert(reference != NULL && dest != NULL);
    if (reference == NULL || dest == NULL) {
        return SECFailure;
    }

    if (SEC_ASN1EncodeItem(arena, dest, reference,
                           CERT_NoticeReferenceTemplate) == NULL) {
        rv = SECFailure;
    }

    return (rv);
}

SECStatus
CERT_EncodeInhibitAnyExtension(PLArenaPool *arena,
                               CERTCertificateInhibitAny *certInhibitAny,
                               SECItem *dest)
{
    SECStatus rv = SECSuccess;

    PORT_Assert(certInhibitAny != NULL && dest != NULL);
    if (certInhibitAny == NULL || dest == NULL) {
        return SECFailure;
    }

    if (SEC_ASN1EncodeItem(arena, dest, certInhibitAny,
                           CERT_InhibitAnyTemplate) == NULL) {
        rv = SECFailure;
    }
    return (rv);
}
