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

#ifndef NSSPKI_H
#include "nsspki.h"
#endif /* NSSPKI_H */

#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */

#ifndef PKIM_H
#include "pkim.h"
#endif /* PKIM_H */

#ifndef DEV_H
#include "dev.h"
#endif /* DEV_H */

#include "pkistore.h"

#include "pki3hack.h"
#include "pk11func.h"
#include "hasht.h"

#ifndef BASE_H
#include "base.h"
#endif /* BASE_H */

extern const NSSError NSS_ERROR_NOT_FOUND;

/* Creates a certificate from a base object */
NSS_IMPLEMENT NSSCertificate *
nssCertificate_Create(
    nssPKIObject *object)
{
    PRStatus status;
    NSSCertificate *rvCert;
    nssArenaMark *mark;
    NSSArena *arena = object->arena;
    PR_ASSERT(object->instances != NULL && object->numInstances > 0);
    PR_ASSERT(object->lockType == nssPKIMonitor);
    mark = nssArena_Mark(arena);
    rvCert = nss_ZNEW(arena, NSSCertificate);
    if (!rvCert) {
        return (NSSCertificate *)NULL;
    }
    rvCert->object = *object;
    /* XXX should choose instance based on some criteria */
    status = nssCryptokiCertificate_GetAttributes(object->instances[0],
                                                  NULL, /* XXX sessionOpt */
                                                  arena,
                                                  &rvCert->type,
                                                  &rvCert->id,
                                                  &rvCert->encoding,
                                                  &rvCert->issuer,
                                                  &rvCert->serial,
                                                  &rvCert->subject);
    if (status != PR_SUCCESS ||
        !rvCert->encoding.data ||
        !rvCert->encoding.size ||
        !rvCert->issuer.data ||
        !rvCert->issuer.size ||
        !rvCert->serial.data ||
        !rvCert->serial.size) {
        if (mark)
            nssArena_Release(arena, mark);
        return (NSSCertificate *)NULL;
    }
    if (mark)
        nssArena_Unmark(arena, mark);
    return rvCert;
}

NSS_IMPLEMENT NSSCertificate *
nssCertificate_AddRef(
    NSSCertificate *c)
{
    if (c) {
        nssPKIObject_AddRef(&c->object);
    }
    return c;
}

NSS_IMPLEMENT PRStatus
nssCertificate_Destroy(
    NSSCertificate *c)
{
    nssCertificateStoreTrace lockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };
    nssCertificateStoreTrace unlockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };

    if (c) {
        PRUint32 i;
        nssDecodedCert *dc = c->decoding;
        NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
        NSSCryptoContext *cc = c->object.cryptoContext;

        PR_ASSERT(c->object.refCount > 0);

        /* --- LOCK storage --- */
        if (cc) {
            nssCertificateStore_Lock(cc->certStore, &lockTrace);
        } else {
            nssTrustDomain_LockCertCache(td);
        }
        if (PR_ATOMIC_DECREMENT(&c->object.refCount) == 0) {
            /* --- remove cert and UNLOCK storage --- */
            if (cc) {
                nssCertificateStore_RemoveCertLOCKED(cc->certStore, c);
                nssCertificateStore_Unlock(cc->certStore, &lockTrace,
                                           &unlockTrace);
            } else {
                nssTrustDomain_RemoveCertFromCacheLOCKED(td, c);
                nssTrustDomain_UnlockCertCache(td);
            }
            /* free cert data */
            for (i = 0; i < c->object.numInstances; i++) {
                nssCryptokiObject_Destroy(c->object.instances[i]);
            }
            nssPKIObject_DestroyLock(&c->object);
            nssArena_Destroy(c->object.arena);
            nssDecodedCert_Destroy(dc);
        } else {
            /* --- UNLOCK storage --- */
            if (cc) {
                nssCertificateStore_Unlock(cc->certStore,
                                           &lockTrace,
                                           &unlockTrace);
            } else {
                nssTrustDomain_UnlockCertCache(td);
            }
        }
    }
    return PR_SUCCESS;
}

NSS_IMPLEMENT PRStatus
NSSCertificate_Destroy(NSSCertificate *c)
{
    return nssCertificate_Destroy(c);
}

NSS_IMPLEMENT NSSDER *
nssCertificate_GetEncoding(NSSCertificate *c)
{
    if (c->encoding.size > 0 && c->encoding.data) {
        return &c->encoding;
    } else {
        return (NSSDER *)NULL;
    }
}

NSS_IMPLEMENT NSSDER *
nssCertificate_GetIssuer(NSSCertificate *c)
{
    if (c->issuer.size > 0 && c->issuer.data) {
        return &c->issuer;
    } else {
        return (NSSDER *)NULL;
    }
}

NSS_IMPLEMENT NSSDER *
nssCertificate_GetSerialNumber(NSSCertificate *c)
{
    if (c->serial.size > 0 && c->serial.data) {
        return &c->serial;
    } else {
        return (NSSDER *)NULL;
    }
}

NSS_IMPLEMENT NSSDER *
nssCertificate_GetSubject(NSSCertificate *c)
{
    if (c->subject.size > 0 && c->subject.data) {
        return &c->subject;
    } else {
        return (NSSDER *)NULL;
    }
}

/* Returns a copy, Caller must free using nss_ZFreeIf */
NSS_IMPLEMENT NSSUTF8 *
nssCertificate_GetNickname(
    NSSCertificate *c,
    NSSToken *tokenOpt)
{
    return nssPKIObject_GetNicknameForToken(&c->object, tokenOpt);
}

NSS_IMPLEMENT NSSASCII7 *
nssCertificate_GetEmailAddress(NSSCertificate *c)
{
    return c->email;
}

NSS_IMPLEMENT PRStatus
NSSCertificate_DeleteStoredObject(
    NSSCertificate *c,
    NSSCallback *uhh)
{
    return nssPKIObject_DeleteStoredObject(&c->object, uhh, PR_TRUE);
}

NSS_IMPLEMENT PRStatus
NSSCertificate_Validate(
    NSSCertificate *c,
    NSSTime *timeOpt, /* NULL for "now" */
    NSSUsage *usage,
    NSSPolicies *policiesOpt /* NULL for none */
    )
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return PR_FAILURE;
}

NSS_IMPLEMENT void ** /* void *[] */
    NSSCertificate_ValidateCompletely(
        NSSCertificate *c,
        NSSTime *timeOpt, /* NULL for "now" */
        NSSUsage *usage,
        NSSPolicies *policiesOpt, /* NULL for none */
        void **rvOpt,             /* NULL for allocate */
        PRUint32 rvLimit,         /* zero for no limit */
        NSSArena *arenaOpt        /* NULL for heap */
        )
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT PRStatus
NSSCertificate_ValidateAndDiscoverUsagesAndPolicies(
    NSSCertificate *c,
    NSSTime **notBeforeOutOpt,
    NSSTime **notAfterOutOpt,
    void *allowedUsages,
    void *disallowedUsages,
    void *allowedPolicies,
    void *disallowedPolicies,
    /* more args.. work on this fgmr */
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return PR_FAILURE;
}

NSS_IMPLEMENT NSSDER *
NSSCertificate_Encode(
    NSSCertificate *c,
    NSSDER *rvOpt,
    NSSArena *arenaOpt)
{
    /* Item, DER, BER are all typedefs now... */
    return nssItem_Duplicate((NSSItem *)&c->encoding, arenaOpt, rvOpt);
}

NSS_IMPLEMENT nssDecodedCert *
nssCertificate_GetDecoding(
    NSSCertificate *c)
{
    nssDecodedCert *deco = NULL;
    if (c->type == NSSCertificateType_PKIX) {
        (void)STAN_GetCERTCertificate(c);
    }
    nssPKIObject_Lock(&c->object);
    if (!c->decoding) {
        deco = nssDecodedCert_Create(NULL, &c->encoding, c->type);
        PORT_Assert(!c->decoding);
        c->decoding = deco;
    } else {
        deco = c->decoding;
    }
    nssPKIObject_Unlock(&c->object);
    return deco;
}

static NSSCertificate **
filter_subject_certs_for_id(
    NSSCertificate **subjectCerts,
    void *id)
{
    NSSCertificate **si;
    nssDecodedCert *dcp;
    int nextOpenSlot = 0;
    int i;
    nssCertIDMatch matchLevel = nssCertIDMatch_Unknown;
    nssCertIDMatch match;

    /* walk the subject certs */
    for (si = subjectCerts; *si; si++) {
        dcp = nssCertificate_GetDecoding(*si);
        if (!dcp) {
            NSSCertificate_Destroy(*si);
            continue;
        }
        match = dcp->matchIdentifier(dcp, id);
        switch (match) {
            case nssCertIDMatch_Yes:
                if (matchLevel == nssCertIDMatch_Unknown) {
                    /* we have non-definitive matches, forget them */
                    for (i = 0; i < nextOpenSlot; i++) {
                        NSSCertificate_Destroy(subjectCerts[i]);
                        subjectCerts[i] = NULL;
                    }
                    nextOpenSlot = 0;
                    /* only keep definitive matches from now on */
                    matchLevel = nssCertIDMatch_Yes;
                }
                /* keep the cert */
                subjectCerts[nextOpenSlot++] = *si;
                break;
            case nssCertIDMatch_Unknown:
                if (matchLevel == nssCertIDMatch_Unknown) {
                    /* only have non-definitive matches so far, keep it */
                    subjectCerts[nextOpenSlot++] = *si;
                    break;
                }
            /* else fall through, we have a definitive match already */
            case nssCertIDMatch_No:
            default:
                NSSCertificate_Destroy(*si);
                *si = NULL;
        }
    }
    subjectCerts[nextOpenSlot] = NULL;
    return subjectCerts;
}

static NSSCertificate **
filter_certs_for_valid_issuers(NSSCertificate **certs)
{
    NSSCertificate **cp;
    nssDecodedCert *dcp;
    int nextOpenSlot = 0;

    for (cp = certs; *cp; cp++) {
        dcp = nssCertificate_GetDecoding(*cp);
        if (dcp && dcp->isValidIssuer(dcp)) {
            certs[nextOpenSlot++] = *cp;
        } else {
            NSSCertificate_Destroy(*cp);
        }
    }
    certs[nextOpenSlot] = NULL;
    return certs;
}

static NSSCertificate *
find_cert_issuer(
    NSSCertificate *c,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSTrustDomain *td,
    NSSCryptoContext *cc)
{
    NSSArena *arena;
    NSSCertificate **certs = NULL;
    NSSCertificate **ccIssuers = NULL;
    NSSCertificate **tdIssuers = NULL;
    NSSCertificate *issuer = NULL;

    if (!cc)
        cc = c->object.cryptoContext;
    if (!td)
        td = NSSCertificate_GetTrustDomain(c);
    arena = nssArena_Create();
    if (!arena) {
        return (NSSCertificate *)NULL;
    }
    if (cc) {
        ccIssuers = nssCryptoContext_FindCertificatesBySubject(cc,
                                                               &c->issuer,
                                                               NULL,
                                                               0,
                                                               arena);
    }
    if (td)
        tdIssuers = nssTrustDomain_FindCertificatesBySubject(td,
                                                             &c->issuer,
                                                             NULL,
                                                             0,
                                                             arena);
    certs = nssCertificateArray_Join(ccIssuers, tdIssuers);
    if (certs) {
        nssDecodedCert *dc = NULL;
        void *issuerID = NULL;
        dc = nssCertificate_GetDecoding(c);
        if (dc) {
            issuerID = dc->getIssuerIdentifier(dc);
        }
        /* XXX review based on CERT_FindCertIssuer
         * this function is not using the authCertIssuer field as a fallback
         * if authority key id does not exist
         */
        if (issuerID) {
            certs = filter_subject_certs_for_id(certs, issuerID);
        }
        certs = filter_certs_for_valid_issuers(certs);
        issuer = nssCertificateArray_FindBestCertificate(certs,
                                                         timeOpt,
                                                         usage,
                                                         policiesOpt);
        nssCertificateArray_Destroy(certs);
    }
    nssArena_Destroy(arena);
    return issuer;
}

/* This function returns the built chain, as far as it gets,
** even if/when it fails to find an issuer, and returns PR_FAILURE
*/
NSS_IMPLEMENT NSSCertificate **
nssCertificate_BuildChain(
    NSSCertificate *c,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCertificate **rvOpt,
    PRUint32 rvLimit,
    NSSArena *arenaOpt,
    PRStatus *statusOpt,
    NSSTrustDomain *td,
    NSSCryptoContext *cc)
{
    NSSCertificate **rvChain = NULL;
    NSSUsage issuerUsage = *usage;
    nssPKIObjectCollection *collection = NULL;
    PRUint32 rvCount = 0;
    PRStatus st;
    PRStatus ret = PR_SUCCESS;

    if (!c || !cc ||
        (!td && (td = NSSCertificate_GetTrustDomain(c)) == NULL)) {
        goto loser;
    }
    /* bump the usage up to CA level */
    issuerUsage.nss3lookingForCA = PR_TRUE;
    collection = nssCertificateCollection_Create(td, NULL);
    if (!collection)
        goto loser;
    st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
    if (st != PR_SUCCESS)
        goto loser;
    for (rvCount = 1; (!rvLimit || rvCount < rvLimit); ++rvCount) {
        CERTCertificate *cCert = STAN_GetCERTCertificate(c);
        if (cCert->isRoot) {
            /* not including the issuer of the self-signed cert, which is,
             * of course, itself
             */
            break;
        }
        c = find_cert_issuer(c, timeOpt, &issuerUsage, policiesOpt, td, cc);
        if (!c) {
            ret = PR_FAILURE;
            break;
        }
        st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
        nssCertificate_Destroy(c); /* collection has it */
        if (st != PR_SUCCESS)
            goto loser;
    }
    rvChain = nssPKIObjectCollection_GetCertificates(collection,
                                                     rvOpt,
                                                     rvLimit,
                                                     arenaOpt);
    if (rvChain) {
        nssPKIObjectCollection_Destroy(collection);
        if (statusOpt)
            *statusOpt = ret;
        if (ret != PR_SUCCESS)
            nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
        return rvChain;
    }

loser:
    if (collection)
        nssPKIObjectCollection_Destroy(collection);
    if (statusOpt)
        *statusOpt = PR_FAILURE;
    nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
    return rvChain;
}

NSS_IMPLEMENT NSSCertificate **
NSSCertificate_BuildChain(
    NSSCertificate *c,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCertificate **rvOpt,
    PRUint32 rvLimit, /* zero for no limit */
    NSSArena *arenaOpt,
    PRStatus *statusOpt,
    NSSTrustDomain *td,
    NSSCryptoContext *cc)
{
    return nssCertificate_BuildChain(c, timeOpt, usage, policiesOpt,
                                     rvOpt, rvLimit, arenaOpt, statusOpt,
                                     td, cc);
}

NSS_IMPLEMENT NSSCryptoContext *
nssCertificate_GetCryptoContext(NSSCertificate *c)
{
    return c->object.cryptoContext;
}

NSS_IMPLEMENT NSSTrustDomain *
nssCertificate_GetTrustDomain(NSSCertificate *c)
{
    return c->object.trustDomain;
}

NSS_IMPLEMENT NSSTrustDomain *
NSSCertificate_GetTrustDomain(NSSCertificate *c)
{
    return nssCertificate_GetTrustDomain(c);
}

NSS_IMPLEMENT NSSToken *
NSSCertificate_GetToken(
    NSSCertificate *c,
    PRStatus *statusOpt)
{
    return (NSSToken *)NULL;
}

NSS_IMPLEMENT NSSSlot *
NSSCertificate_GetSlot(
    NSSCertificate *c,
    PRStatus *statusOpt)
{
    return (NSSSlot *)NULL;
}

NSS_IMPLEMENT NSSModule *
NSSCertificate_GetModule(
    NSSCertificate *c,
    PRStatus *statusOpt)
{
    return (NSSModule *)NULL;
}

NSS_IMPLEMENT NSSItem *
NSSCertificate_Encrypt(
    NSSCertificate *c,
    NSSAlgorithmAndParameters *apOpt,
    NSSItem *data,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT PRStatus
NSSCertificate_Verify(
    NSSCertificate *c,
    NSSAlgorithmAndParameters *apOpt,
    NSSItem *data,
    NSSItem *signature,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return PR_FAILURE;
}

NSS_IMPLEMENT NSSItem *
NSSCertificate_VerifyRecover(
    NSSCertificate *c,
    NSSAlgorithmAndParameters *apOpt,
    NSSItem *signature,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT NSSItem *
NSSCertificate_WrapSymmetricKey(
    NSSCertificate *c,
    NSSAlgorithmAndParameters *apOpt,
    NSSSymmetricKey *keyToWrap,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT NSSCryptoContext *
NSSCertificate_CreateCryptoContext(
    NSSCertificate *c,
    NSSAlgorithmAndParameters *apOpt,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT NSSPublicKey *
NSSCertificate_GetPublicKey(
    NSSCertificate *c)
{
#if 0
    CK_ATTRIBUTE pubktemplate[] = {
    { CKA_CLASS,   NULL, 0 },
    { CKA_ID,      NULL, 0 },
    { CKA_SUBJECT, NULL, 0 }
    };
    PRStatus nssrv;
    CK_ULONG count = sizeof(pubktemplate) / sizeof(pubktemplate[0]);
    NSS_CK_SET_ATTRIBUTE_ITEM(pubktemplate, 0, &g_ck_class_pubkey);
    if (c->id.size > 0) {
    /* CKA_ID */
    NSS_CK_ITEM_TO_ATTRIBUTE(&c->id, &pubktemplate[1]);
    } else {
    /* failure, yes? */
    return (NSSPublicKey *)NULL;
    }
    if (c->subject.size > 0) {
    /* CKA_SUBJECT */
    NSS_CK_ITEM_TO_ATTRIBUTE(&c->subject, &pubktemplate[2]);
    } else {
    /* failure, yes? */
    return (NSSPublicKey *)NULL;
    }
    /* Try the cert's token first */
    if (c->token) {
    nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count);
    }
#endif
    /* Try all other key tokens */
    return (NSSPublicKey *)NULL;
}

NSS_IMPLEMENT NSSPrivateKey *
NSSCertificate_FindPrivateKey(
    NSSCertificate *c,
    NSSCallback *uhh)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT PRBool
NSSCertificate_IsPrivateKeyAvailable(
    NSSCertificate *c,
    NSSCallback *uhh,
    PRStatus *statusOpt)
{
    PRBool isUser = PR_FALSE;
    nssCryptokiObject **ip;
    nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
    if (!instances) {
        return PR_FALSE;
    }
    for (ip = instances; *ip; ip++) {
        nssCryptokiObject *instance = *ip;
        if (nssToken_IsPrivateKeyAvailable(instance->token, c, instance)) {
            isUser = PR_TRUE;
        }
    }
    nssCryptokiObjectArray_Destroy(instances);
    return isUser;
}

/* sort the subject cert list from newest to oldest */
PRIntn
nssCertificate_SubjectListSort(
    void *v1,
    void *v2)
{
    NSSCertificate *c1 = (NSSCertificate *)v1;
    NSSCertificate *c2 = (NSSCertificate *)v2;
    nssDecodedCert *dc1 = nssCertificate_GetDecoding(c1);
    nssDecodedCert *dc2 = nssCertificate_GetDecoding(c2);
    if (!dc1) {
        return dc2 ? 1 : 0;
    } else if (!dc2) {
        return -1;
    } else {
        return dc1->isNewerThan(dc1, dc2) ? -1 : 1;
    }
}

NSS_IMPLEMENT PRBool
NSSUserCertificate_IsStillPresent(
    NSSUserCertificate *uc,
    PRStatus *statusOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return PR_FALSE;
}

NSS_IMPLEMENT NSSItem *
NSSUserCertificate_Decrypt(
    NSSUserCertificate *uc,
    NSSAlgorithmAndParameters *apOpt,
    NSSItem *data,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT NSSItem *
NSSUserCertificate_Sign(
    NSSUserCertificate *uc,
    NSSAlgorithmAndParameters *apOpt,
    NSSItem *data,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT NSSItem *
NSSUserCertificate_SignRecover(
    NSSUserCertificate *uc,
    NSSAlgorithmAndParameters *apOpt,
    NSSItem *data,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT NSSSymmetricKey *
NSSUserCertificate_UnwrapSymmetricKey(
    NSSUserCertificate *uc,
    NSSAlgorithmAndParameters *apOpt,
    NSSItem *wrappedKey,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT NSSSymmetricKey *
NSSUserCertificate_DeriveSymmetricKey(
    NSSUserCertificate *uc, /* provides private key */
    NSSCertificate *c,      /* provides public key */
    NSSAlgorithmAndParameters *apOpt,
    NSSOID *target,
    PRUint32 keySizeOpt, /* zero for best allowed */
    NSSOperations operations,
    NSSCallback *uhh)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT nssSMIMEProfile *
nssSMIMEProfile_Create(
    NSSCertificate *cert,
    NSSItem *profileTime,
    NSSItem *profileData)
{
    NSSArena *arena;
    nssSMIMEProfile *rvProfile;
    nssPKIObject *object;
    NSSTrustDomain *td = nssCertificate_GetTrustDomain(cert);
    NSSCryptoContext *cc = nssCertificate_GetCryptoContext(cert);
    arena = nssArena_Create();
    if (!arena) {
        return NULL;
    }
    object = nssPKIObject_Create(arena, NULL, td, cc, nssPKILock);
    if (!object) {
        goto loser;
    }
    rvProfile = nss_ZNEW(arena, nssSMIMEProfile);
    if (!rvProfile) {
        goto loser;
    }
    rvProfile->object = *object;
    rvProfile->certificate = cert;
    rvProfile->email = nssUTF8_Duplicate(cert->email, arena);
    rvProfile->subject = nssItem_Duplicate(&cert->subject, arena, NULL);
    if (profileTime) {
        rvProfile->profileTime = nssItem_Duplicate(profileTime, arena, NULL);
    }
    if (profileData) {
        rvProfile->profileData = nssItem_Duplicate(profileData, arena, NULL);
    }
    return rvProfile;
loser:
    if (object)
        nssPKIObject_Destroy(object);
    else if (arena)
        nssArena_Destroy(arena);
    return (nssSMIMEProfile *)NULL;
}

/* execute a callback function on all members of a cert list */
NSS_EXTERN PRStatus
nssCertificateList_DoCallback(
    nssList *certList,
    PRStatus (*callback)(NSSCertificate *c, void *arg),
    void *arg)
{
    nssListIterator *certs;
    NSSCertificate *cert;
    certs = nssList_CreateIterator(certList);
    if (!certs) {
        return PR_FAILURE;
    }
    for (cert = (NSSCertificate *)nssListIterator_Start(certs);
         cert != (NSSCertificate *)NULL;
         cert = (NSSCertificate *)nssListIterator_Next(certs)) {
        (void)(*callback)(cert, arg);
    }
    nssListIterator_Finish(certs);
    nssListIterator_Destroy(certs);
    return PR_SUCCESS;
}

static PRStatus
add_ref_callback(NSSCertificate *c, void *a)
{
    nssCertificate_AddRef(c);
    return PR_SUCCESS;
}

NSS_IMPLEMENT void
nssCertificateList_AddReferences(
    nssList *certList)
{
    (void)nssCertificateList_DoCallback(certList, add_ref_callback, NULL);
}

/*
 * Is this trust record safe to apply to all certs of the same issuer/SN
 * independent of the cert matching the hash. This is only true is the trust
 * is unknown or distrusted. In general this feature is only useful to
 * explicitly distrusting certs. It is not safe to use to trust certs, so
 * only allow unknown and untrusted trust types.
 */
PRBool
nssTrust_IsSafeToIgnoreCertHash(nssTrustLevel serverAuth,
                                nssTrustLevel clientAuth, nssTrustLevel codeSigning,
                                nssTrustLevel email, PRBool stepup)
{
    /* step up is a trust type, if it's on, we must have a hash for the cert */
    if (stepup) {
        return PR_FALSE;
    }
    if ((serverAuth != nssTrustLevel_Unknown) &&
        (serverAuth != nssTrustLevel_NotTrusted)) {
        return PR_FALSE;
    }
    if ((clientAuth != nssTrustLevel_Unknown) &&
        (clientAuth != nssTrustLevel_NotTrusted)) {
        return PR_FALSE;
    }
    if ((codeSigning != nssTrustLevel_Unknown) &&
        (codeSigning != nssTrustLevel_NotTrusted)) {
        return PR_FALSE;
    }
    if ((email != nssTrustLevel_Unknown) &&
        (email != nssTrustLevel_NotTrusted)) {
        return PR_FALSE;
    }
    /* record only has Unknown and Untrusted entries, ok to accept without a
     * hash */
    return PR_TRUE;
}

NSS_IMPLEMENT NSSTrust *
nssTrust_Create(
    nssPKIObject *object,
    NSSItem *certData)
{
    PRStatus status;
    PRUint32 i;
    PRUint32 lastTrustOrder, myTrustOrder;
    unsigned char sha1_hashcmp[SHA1_LENGTH];
    unsigned char sha1_hashin[SHA1_LENGTH];
    NSSItem sha1_hash;
    NSSTrust *rvt;
    nssCryptokiObject *instance;
    nssTrustLevel serverAuth, clientAuth, codeSigning, emailProtection;
    SECStatus rv; /* Should be stan flavor */
    PRBool stepUp;

    lastTrustOrder = 1 << 16; /* just make it big */
    PR_ASSERT(object->instances != NULL && object->numInstances > 0);
    rvt = nss_ZNEW(object->arena, NSSTrust);
    if (!rvt) {
        return (NSSTrust *)NULL;
    }
    rvt->object = *object;

    /* should be stan flavor of Hashbuf */
    rv = PK11_HashBuf(SEC_OID_SHA1, sha1_hashcmp, certData->data, certData->size);
    if (rv != SECSuccess) {
        return (NSSTrust *)NULL;
    }
    sha1_hash.data = sha1_hashin;
    sha1_hash.size = sizeof(sha1_hashin);
    /* trust has to peek into the base object members */
    nssPKIObject_Lock(object);
    for (i = 0; i < object->numInstances; i++) {
        instance = object->instances[i];
        myTrustOrder = nssToken_GetTrustOrder(instance->token);
        status = nssCryptokiTrust_GetAttributes(instance, NULL,
                                                &sha1_hash,
                                                &serverAuth,
                                                &clientAuth,
                                                &codeSigning,
                                                &emailProtection,
                                                &stepUp);
        if (status != PR_SUCCESS) {
            nssPKIObject_Unlock(object);
            return (NSSTrust *)NULL;
        }
        /* if no hash is specified, then trust applies to all certs with
         * this issuer/SN. NOTE: This is only true for entries that
         * have distrust and unknown record */
        if (!(
                /* we continue if there is no hash, and the trust type is
                 * safe to accept without a hash ... or ... */
                ((sha1_hash.size == 0) &&
                 nssTrust_IsSafeToIgnoreCertHash(serverAuth, clientAuth,
                                                 codeSigning, emailProtection,
                                                 stepUp)) ||
                /* we have a hash of the correct size, and it matches */
                ((sha1_hash.size == SHA1_LENGTH) && (PORT_Memcmp(sha1_hashin,
                                                                 sha1_hashcmp,
                                                                 SHA1_LENGTH) == 0)))) {
            nssPKIObject_Unlock(object);
            return (NSSTrust *)NULL;
        }
        if (rvt->serverAuth == nssTrustLevel_Unknown ||
            myTrustOrder < lastTrustOrder) {
            rvt->serverAuth = serverAuth;
        }
        if (rvt->clientAuth == nssTrustLevel_Unknown ||
            myTrustOrder < lastTrustOrder) {
            rvt->clientAuth = clientAuth;
        }
        if (rvt->emailProtection == nssTrustLevel_Unknown ||
            myTrustOrder < lastTrustOrder) {
            rvt->emailProtection = emailProtection;
        }
        if (rvt->codeSigning == nssTrustLevel_Unknown ||
            myTrustOrder < lastTrustOrder) {
            rvt->codeSigning = codeSigning;
        }
        rvt->stepUpApproved = stepUp;
        lastTrustOrder = myTrustOrder;
    }
    nssPKIObject_Unlock(object);
    return rvt;
}

NSS_IMPLEMENT NSSTrust *
nssTrust_AddRef(NSSTrust *trust)
{
    if (trust) {
        nssPKIObject_AddRef(&trust->object);
    }
    return trust;
}

NSS_IMPLEMENT PRStatus
nssTrust_Destroy(NSSTrust *trust)
{
    if (trust) {
        (void)nssPKIObject_Destroy(&trust->object);
    }
    return PR_SUCCESS;
}

NSS_IMPLEMENT nssSMIMEProfile *
nssSMIMEProfile_AddRef(nssSMIMEProfile *profile)
{
    if (profile) {
        nssPKIObject_AddRef(&profile->object);
    }
    return profile;
}

NSS_IMPLEMENT PRStatus
nssSMIMEProfile_Destroy(nssSMIMEProfile *profile)
{
    if (profile) {
        (void)nssPKIObject_Destroy(&profile->object);
    }
    return PR_SUCCESS;
}

NSS_IMPLEMENT NSSCRL *
nssCRL_Create(nssPKIObject *object)
{
    PRStatus status;
    NSSCRL *rvCRL;
    NSSArena *arena = object->arena;
    PR_ASSERT(object->instances != NULL && object->numInstances > 0);
    rvCRL = nss_ZNEW(arena, NSSCRL);
    if (!rvCRL) {
        return (NSSCRL *)NULL;
    }
    rvCRL->object = *object;
    /* XXX should choose instance based on some criteria */
    status = nssCryptokiCRL_GetAttributes(object->instances[0],
                                          NULL, /* XXX sessionOpt */
                                          arena,
                                          &rvCRL->encoding,
                                          NULL, /* subject */
                                          NULL, /* class */
                                          &rvCRL->url,
                                          &rvCRL->isKRL);
    if (status != PR_SUCCESS) {
        if (!arena) {
            nssPKIObject_Destroy((nssPKIObject *)rvCRL);
        }
        return (NSSCRL *)NULL;
    }
    return rvCRL;
}

NSS_IMPLEMENT NSSCRL *
nssCRL_AddRef(NSSCRL *crl)
{
    if (crl) {
        nssPKIObject_AddRef(&crl->object);
    }
    return crl;
}

NSS_IMPLEMENT PRStatus
nssCRL_Destroy(NSSCRL *crl)
{
    if (crl) {
        (void)nssPKIObject_Destroy(&crl->object);
    }
    return PR_SUCCESS;
}

NSS_IMPLEMENT PRStatus
nssCRL_DeleteStoredObject(
    NSSCRL *crl,
    NSSCallback *uhh)
{
    return nssPKIObject_DeleteStoredObject(&crl->object, uhh, PR_TRUE);
}

NSS_IMPLEMENT NSSDER *
nssCRL_GetEncoding(NSSCRL *crl)
{
    if (crl && crl->encoding.data != NULL && crl->encoding.size > 0) {
        return &crl->encoding;
    } else {
        return (NSSDER *)NULL;
    }
}
