/* 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/. */
/*
 * This file manages Netscape specific PKCS #11 objects (CRLs, Trust objects,
 * etc).
 */

#include "secport.h"
#include "seccomon.h"
#include "secmod.h"
#include "secmodi.h"
#include "secmodti.h"
#include "pkcs11.h"
#include "pk11func.h"
#include "cert.h"
#include "certi.h"
#include "secitem.h"
#include "sechash.h"
#include "secoid.h"

#include "certdb.h"
#include "secerr.h"

#include "pki3hack.h"
#include "dev3hack.h"

#include "devm.h"
#include "pki.h"
#include "pkim.h"

extern const NSSError NSS_ERROR_NOT_FOUND;

CK_TRUST
pk11_GetTrustField(PK11SlotInfo *slot, PLArenaPool *arena,
                   CK_OBJECT_HANDLE id, CK_ATTRIBUTE_TYPE type)
{
    CK_TRUST rv = 0;
    SECItem item;

    item.data = NULL;
    item.len = 0;

    if (SECSuccess == PK11_ReadAttribute(slot, id, type, arena, &item)) {
        PORT_Assert(item.len == sizeof(CK_TRUST));
        PORT_Memcpy(&rv, item.data, sizeof(CK_TRUST));
        /* Damn, is there an endian problem here? */
        return rv;
    }

    return 0;
}

PRBool
pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert, CERTCertTrust *trust)
{
    PLArenaPool *arena;

    CK_ATTRIBUTE tobjTemplate[] = {
        { CKA_CLASS, NULL, 0 },
        { CKA_CERT_SHA1_HASH, NULL, 0 },
    };

    CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
    CK_OBJECT_HANDLE tobjID;
    unsigned char sha1_hash[SHA1_LENGTH];

    CK_TRUST serverAuth, codeSigning, emailProtection, clientAuth;

    PK11_HashBuf(SEC_OID_SHA1, sha1_hash, cert->derCert.data, cert->derCert.len);

    PK11_SETATTRS(&tobjTemplate[0], CKA_CLASS, &tobjc, sizeof(tobjc));
    PK11_SETATTRS(&tobjTemplate[1], CKA_CERT_SHA1_HASH, sha1_hash,
                  SHA1_LENGTH);

    tobjID = pk11_FindObjectByTemplate(slot, tobjTemplate,
                                       sizeof(tobjTemplate) / sizeof(tobjTemplate[0]));
    if (CK_INVALID_HANDLE == tobjID) {
        return PR_FALSE;
    }

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (NULL == arena)
        return PR_FALSE;

    /* Unfortunately, it seems that PK11_GetAttributes doesn't deal
     * well with nonexistent attributes.  I guess we have to check
     * the trust info fields one at a time.
     */

    /* We could verify CKA_CERT_HASH here */

    /* We could verify CKA_EXPIRES here */

    /* "Purpose" trust information */
    serverAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_SERVER_AUTH);
    clientAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CLIENT_AUTH);
    codeSigning = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CODE_SIGNING);
    emailProtection = pk11_GetTrustField(slot, arena, tobjID,
                                         CKA_TRUST_EMAIL_PROTECTION);
    /* Here's where the fun logic happens.  We have to map back from the
     * key usage, extended key usage, purpose, and possibly other trust values
     * into the old trust-flags bits.  */

    /* First implementation: keep it simple for testing.  We can study what other
     * mappings would be appropriate and add them later.. fgmr 20000724 */

    if (serverAuth == CKT_NSS_TRUSTED) {
        trust->sslFlags |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
    }

    if (serverAuth == CKT_NSS_TRUSTED_DELEGATOR) {
        trust->sslFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA |
                           CERTDB_NS_TRUSTED_CA;
    }
    if (clientAuth == CKT_NSS_TRUSTED_DELEGATOR) {
        trust->sslFlags |= CERTDB_TRUSTED_CLIENT_CA;
    }

    if (emailProtection == CKT_NSS_TRUSTED) {
        trust->emailFlags |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
    }

    if (emailProtection == CKT_NSS_TRUSTED_DELEGATOR) {
        trust->emailFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA;
    }

    if (codeSigning == CKT_NSS_TRUSTED) {
        trust->objectSigningFlags |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
    }

    if (codeSigning == CKT_NSS_TRUSTED_DELEGATOR) {
        trust->objectSigningFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA;
    }

    /* There's certainly a lot more logic that can go here.. */

    PORT_FreeArena(arena, PR_FALSE);

    return PR_TRUE;
}

static SECStatus
pk11_CollectCrls(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID, void *arg)
{
    SECItem derCrl;
    CERTCrlHeadNode *head = (CERTCrlHeadNode *)arg;
    CERTCrlNode *new_node = NULL;
    CK_ATTRIBUTE fetchCrl[3] = {
        { CKA_VALUE, NULL, 0 },
        { CKA_NETSCAPE_KRL, NULL, 0 },
        { CKA_NETSCAPE_URL, NULL, 0 },
    };
    const int fetchCrlSize = sizeof(fetchCrl) / sizeof(fetchCrl[2]);
    CK_RV crv;
    SECStatus rv = SECFailure;

    crv = PK11_GetAttributes(head->arena, slot, crlID, fetchCrl, fetchCrlSize);
    if (CKR_OK != crv) {
        PORT_SetError(PK11_MapError(crv));
        goto loser;
    }

    if (!fetchCrl[1].pValue) {
        PORT_SetError(SEC_ERROR_CRL_INVALID);
        goto loser;
    }

    new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena, sizeof(CERTCrlNode));
    if (new_node == NULL) {
        goto loser;
    }

    if (*((CK_BBOOL *)fetchCrl[1].pValue))
        new_node->type = SEC_KRL_TYPE;
    else
        new_node->type = SEC_CRL_TYPE;

    derCrl.type = siBuffer;
    derCrl.data = (unsigned char *)fetchCrl[0].pValue;
    derCrl.len = fetchCrl[0].ulValueLen;
    new_node->crl = CERT_DecodeDERCrl(head->arena, &derCrl, new_node->type);
    if (new_node->crl == NULL) {
        goto loser;
    }

    if (fetchCrl[2].pValue) {
        int nnlen = fetchCrl[2].ulValueLen;
        new_node->crl->url = (char *)PORT_ArenaAlloc(head->arena, nnlen + 1);
        if (!new_node->crl->url) {
            goto loser;
        }
        PORT_Memcpy(new_node->crl->url, fetchCrl[2].pValue, nnlen);
        new_node->crl->url[nnlen] = 0;
    } else {
        new_node->crl->url = NULL;
    }

    new_node->next = NULL;
    if (head->last) {
        head->last->next = new_node;
        head->last = new_node;
    } else {
        head->first = head->last = new_node;
    }
    rv = SECSuccess;

loser:
    return (rv);
}

/*
 * Return a list of all the CRLs .
 * CRLs are allocated in the list's arena.
 */
SECStatus
PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx)
{
    pk11TraverseSlot creater;
    CK_ATTRIBUTE theTemplate[2];
    CK_ATTRIBUTE *attrs;
    CK_OBJECT_CLASS certClass = CKO_NETSCAPE_CRL;
    CK_BBOOL isKrl = CK_FALSE;

    attrs = theTemplate;
    PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass));
    attrs++;
    if (type != -1) {
        isKrl = (CK_BBOOL)(type == SEC_KRL_TYPE);
        PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, &isKrl, sizeof(isKrl));
        attrs++;
    }

    creater.callback = pk11_CollectCrls;
    creater.callbackArg = (void *)nodes;
    creater.findTemplate = theTemplate;
    creater.templateCount = (attrs - theTemplate);

    return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx);
}

struct crlOptionsStr {
    CERTCrlHeadNode *head;
    PRInt32 decodeOptions;
};

typedef struct crlOptionsStr crlOptions;

static SECStatus
pk11_RetrieveCrlsCallback(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID,
                          void *arg)
{
    SECItem *derCrl = NULL;
    crlOptions *options = (crlOptions *)arg;
    CERTCrlHeadNode *head = options->head;
    CERTCrlNode *new_node = NULL;
    CK_ATTRIBUTE fetchCrl[3] = {
        { CKA_VALUE, NULL, 0 },
        { CKA_NETSCAPE_KRL, NULL, 0 },
        { CKA_NETSCAPE_URL, NULL, 0 },
    };
    const int fetchCrlSize = sizeof(fetchCrl) / sizeof(fetchCrl[2]);
    CK_RV crv;
    SECStatus rv = SECFailure;
    PRBool adopted = PR_FALSE; /* whether the CRL adopted the DER memory
                                  successfully */
    int i;

    crv = PK11_GetAttributes(NULL, slot, crlID, fetchCrl, fetchCrlSize);
    if (CKR_OK != crv) {
        PORT_SetError(PK11_MapError(crv));
        goto loser;
    }

    if (!fetchCrl[1].pValue) {
        /* reject KRLs */
        PORT_SetError(SEC_ERROR_CRL_INVALID);
        goto loser;
    }

    new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena,
                                              sizeof(CERTCrlNode));
    if (new_node == NULL) {
        goto loser;
    }

    new_node->type = SEC_CRL_TYPE;

    derCrl = SECITEM_AllocItem(NULL, NULL, 0);
    if (!derCrl) {
        goto loser;
    }
    derCrl->type = siBuffer;
    derCrl->data = (unsigned char *)fetchCrl[0].pValue;
    derCrl->len = fetchCrl[0].ulValueLen;
    new_node->crl = CERT_DecodeDERCrlWithFlags(NULL, derCrl, new_node->type,
                                               options->decodeOptions);
    if (new_node->crl == NULL) {
        goto loser;
    }
    adopted = PR_TRUE; /* now that the CRL has adopted the DER memory,
                          we won't need to free it upon exit */

    if (fetchCrl[2].pValue && fetchCrl[2].ulValueLen) {
        /* copy the URL if there is one */
        int nnlen = fetchCrl[2].ulValueLen;
        new_node->crl->url = (char *)PORT_ArenaAlloc(new_node->crl->arena,
                                                     nnlen + 1);
        if (!new_node->crl->url) {
            goto loser;
        }
        PORT_Memcpy(new_node->crl->url, fetchCrl[2].pValue, nnlen);
        new_node->crl->url[nnlen] = 0;
    } else {
        new_node->crl->url = NULL;
    }

    new_node->next = NULL;
    if (head->last) {
        head->last->next = new_node;
        head->last = new_node;
    } else {
        head->first = head->last = new_node;
    }
    rv = SECSuccess;
    new_node->crl->slot = PK11_ReferenceSlot(slot);
    new_node->crl->pkcs11ID = crlID;

loser:
    /* free attributes that weren't adopted by the CRL */
    for (i = 1; i < fetchCrlSize; i++) {
        if (fetchCrl[i].pValue) {
            PORT_Free(fetchCrl[i].pValue);
        }
    }
    /* free the DER if the CRL object didn't adopt it */
    if (fetchCrl[0].pValue && PR_FALSE == adopted) {
        PORT_Free(fetchCrl[0].pValue);
    }
    if (derCrl && !adopted) {
        /* clear the data fields, which we already took care of above */
        derCrl->data = NULL;
        derCrl->len = 0;
        /* free the memory for the SECItem structure itself */
        SECITEM_FreeItem(derCrl, PR_TRUE);
    }
    return (rv);
}

/*
 * Return a list of CRLs matching specified issuer and type
 * CRLs are not allocated in the list's arena, but rather in their own,
 * arena, so that they can be used individually in the CRL cache .
 * CRLs are always partially decoded for efficiency.
 */
SECStatus
pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem *issuer,
                  void *wincx)
{
    pk11TraverseSlot creater;
    CK_ATTRIBUTE theTemplate[2];
    CK_ATTRIBUTE *attrs;
    CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
    crlOptions options;

    attrs = theTemplate;
    PK11_SETATTRS(attrs, CKA_CLASS, &crlClass, sizeof(crlClass));
    attrs++;

    options.head = nodes;

    /* - do a partial decoding - we don't need to decode the entries while fetching
       - don't copy the DER for optimal performance - CRL can be very large
       - have the CRL objects adopt the DER, so SEC_DestroyCrl will free it
       - keep bad CRL objects. The CRL cache is interested in them, for
         security purposes. Bad CRL objects are a sign of something amiss.
     */

    options.decodeOptions = CRL_DECODE_SKIP_ENTRIES | CRL_DECODE_DONT_COPY_DER |
                            CRL_DECODE_ADOPT_HEAP_DER | CRL_DECODE_KEEP_BAD_CRL;
    if (issuer) {
        PK11_SETATTRS(attrs, CKA_SUBJECT, issuer->data, issuer->len);
        attrs++;
    }

    creater.callback = pk11_RetrieveCrlsCallback;
    creater.callbackArg = (void *)&options;
    creater.findTemplate = theTemplate;
    creater.templateCount = (attrs - theTemplate);

    return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx);
}

/*
 * return the crl associated with a derSubjectName
 */
SECItem *
PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle,
                   SECItem *name, int type, char **pUrl)
{
    NSSCRL **crls, **crlp, *crl = NULL;
    NSSDER subject;
    SECItem *rvItem;
    NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
    char *url = NULL;

    PORT_SetError(0);
    NSSITEM_FROM_SECITEM(&subject, name);
    if (*slot) {
        nssCryptokiObject **instances;
        nssPKIObjectCollection *collection;
        nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
        NSSToken *token = PK11Slot_GetNSSToken(*slot);
        collection = nssCRLCollection_Create(td, NULL);
        if (!collection) {
            goto loser;
        }
        instances = nssToken_FindCRLsBySubject(token, NULL, &subject,
                                               tokenOnly, 0, NULL);
        nssPKIObjectCollection_AddInstances(collection, instances, 0);
        nss_ZFreeIf(instances);
        crls = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL);
        nssPKIObjectCollection_Destroy(collection);
    } else {
        crls = nssTrustDomain_FindCRLsBySubject(td, &subject);
    }
    if ((!crls) || (*crls == NULL)) {
        if (crls) {
            nssCRLArray_Destroy(crls);
        }
        if (NSS_GetError() == NSS_ERROR_NOT_FOUND) {
            PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
        }
        goto loser;
    }
    for (crlp = crls; *crlp; crlp++) {
        if ((!(*crlp)->isKRL && type == SEC_CRL_TYPE) ||
            ((*crlp)->isKRL && type != SEC_CRL_TYPE)) {
            crl = nssCRL_AddRef(*crlp);
            break;
        }
    }
    nssCRLArray_Destroy(crls);
    if (!crl) {
        /* CRL collection was found, but no interesting CRL's were on it.
         * Not an error */
        PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
        goto loser;
    }
    if (crl->url) {
        url = PORT_Strdup(crl->url);
        if (!url) {
            goto loser;
        }
    }
    rvItem = SECITEM_AllocItem(NULL, NULL, crl->encoding.size);
    if (!rvItem) {
        goto loser;
    }
    memcpy(rvItem->data, crl->encoding.data, crl->encoding.size);
    *slot = PK11_ReferenceSlot(crl->object.instances[0]->token->pk11slot);
    *crlHandle = crl->object.instances[0]->handle;
    *pUrl = url;
    nssCRL_Destroy(crl);
    return rvItem;

loser:
    if (url)
        PORT_Free(url);
    if (crl)
        nssCRL_Destroy(crl);
    if (PORT_GetError() == 0) {
        PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
    }
    return NULL;
}

CK_OBJECT_HANDLE
PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
            char *url, int type)
{
    NSSItem derCRL, derSubject;
    NSSToken *token = PK11Slot_GetNSSToken(slot);
    nssCryptokiObject *object;
    PRBool isKRL = (type == SEC_CRL_TYPE) ? PR_FALSE : PR_TRUE;
    CK_OBJECT_HANDLE rvH;

    NSSITEM_FROM_SECITEM(&derSubject, name);
    NSSITEM_FROM_SECITEM(&derCRL, crl);

    object = nssToken_ImportCRL(token, NULL,
                                &derSubject, &derCRL, isKRL, url, PR_TRUE);

    if (object) {
        rvH = object->handle;
        nssCryptokiObject_Destroy(object);
    } else {
        rvH = CK_INVALID_HANDLE;
        PORT_SetError(SEC_ERROR_CRL_IMPORT_FAILED);
    }
    return rvH;
}

/*
 * delete a crl.
 */
SECStatus
SEC_DeletePermCRL(CERTSignedCrl *crl)
{
    PRStatus status;
    NSSToken *token;
    nssCryptokiObject *object;
    PK11SlotInfo *slot = crl->slot;

    if (slot == NULL) {
        PORT_Assert(slot);
        /* shouldn't happen */
        PORT_SetError(SEC_ERROR_CRL_INVALID);
        return SECFailure;
    }
    token = PK11Slot_GetNSSToken(slot);

    object = nss_ZNEW(NULL, nssCryptokiObject);
    if (!object) {
        return SECFailure;
    }
    object->token = nssToken_AddRef(token);
    object->handle = crl->pkcs11ID;
    object->isTokenObject = PR_TRUE;

    status = nssToken_DeleteStoredObject(object);

    nssCryptokiObject_Destroy(object);
    return (status == PR_SUCCESS) ? SECSuccess : SECFailure;
}

/*
 * return the certificate associated with a derCert
 */
SECItem *
PK11_FindSMimeProfile(PK11SlotInfo **slot, char *emailAddr,
                      SECItem *name, SECItem **profileTime)
{
    CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME;
    CK_ATTRIBUTE theTemplate[] = {
        { CKA_SUBJECT, NULL, 0 },
        { CKA_CLASS, NULL, 0 },
        { CKA_NETSCAPE_EMAIL, NULL, 0 },
    };
    CK_ATTRIBUTE smimeData[] = {
        { CKA_SUBJECT, NULL, 0 },
        { CKA_VALUE, NULL, 0 },
    };
    /* if you change the array, change the variable below as well */
    int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
    CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE;
    CK_ATTRIBUTE *attrs = theTemplate;
    CK_RV crv;
    SECItem *emailProfile = NULL;

    if (!emailAddr || !emailAddr[0]) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len);
    attrs++;
    PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass));
    attrs++;
    PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL, emailAddr, strlen(emailAddr));
    attrs++;

    if (*slot) {
        smimeh = pk11_FindObjectByTemplate(*slot, theTemplate, tsize);
    } else {
        PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
                                               PR_FALSE, PR_TRUE, NULL);
        PK11SlotListElement *le;

        if (!list) {
            return NULL;
        }
        /* loop through all the slots */
        for (le = list->head; le; le = le->next) {
            smimeh = pk11_FindObjectByTemplate(le->slot, theTemplate, tsize);
            if (smimeh != CK_INVALID_HANDLE) {
                *slot = PK11_ReferenceSlot(le->slot);
                break;
            }
        }
        PK11_FreeSlotList(list);
    }

    if (smimeh == CK_INVALID_HANDLE) {
        PORT_SetError(SEC_ERROR_NO_KRL);
        return NULL;
    }

    if (profileTime) {
        PK11_SETATTRS(smimeData, CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0);
    }

    crv = PK11_GetAttributes(NULL, *slot, smimeh, smimeData, 2);
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        goto loser;
    }

    if (!profileTime) {
        SECItem profileSubject;

        profileSubject.data = (unsigned char *)smimeData[0].pValue;
        profileSubject.len = smimeData[0].ulValueLen;
        if (!SECITEM_ItemsAreEqual(&profileSubject, name)) {
            goto loser;
        }
    }

    emailProfile = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
    if (emailProfile == NULL) {
        goto loser;
    }

    emailProfile->data = (unsigned char *)smimeData[1].pValue;
    emailProfile->len = smimeData[1].ulValueLen;

    if (profileTime) {
        *profileTime = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
        if (*profileTime) {
            (*profileTime)->data = (unsigned char *)smimeData[0].pValue;
            (*profileTime)->len = smimeData[0].ulValueLen;
        }
    }

loser:
    if (emailProfile == NULL) {
        if (smimeData[1].pValue) {
            PORT_Free(smimeData[1].pValue);
        }
    }
    if (profileTime == NULL || *profileTime == NULL) {
        if (smimeData[0].pValue) {
            PORT_Free(smimeData[0].pValue);
        }
    }
    return emailProfile;
}

SECStatus
PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
                      SECItem *emailProfile, SECItem *profileTime)
{
    CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME;
    CK_BBOOL ck_true = CK_TRUE;
    CK_ATTRIBUTE theTemplate[] = {
        { CKA_CLASS, NULL, 0 },
        { CKA_TOKEN, NULL, 0 },
        { CKA_SUBJECT, NULL, 0 },
        { CKA_NETSCAPE_EMAIL, NULL, 0 },
        { CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0 },
        { CKA_VALUE, NULL, 0 }
    };
    /* if you change the array, change the variable below as well */
    int realSize = 0;
    CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE;
    CK_ATTRIBUTE *attrs = theTemplate;
    CK_SESSION_HANDLE rwsession;
    PK11SlotInfo *free_slot = NULL;
    CK_RV crv;
#ifdef DEBUG
    int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
#endif

    PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass));
    attrs++;
    PK11_SETATTRS(attrs, CKA_TOKEN, &ck_true, sizeof(ck_true));
    attrs++;
    PK11_SETATTRS(attrs, CKA_SUBJECT, derSubj->data, derSubj->len);
    attrs++;
    PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL,
                  emailAddr, PORT_Strlen(emailAddr) + 1);
    attrs++;
    if (profileTime) {
        PK11_SETATTRS(attrs, CKA_NETSCAPE_SMIME_TIMESTAMP, profileTime->data,
                      profileTime->len);
        attrs++;
        PK11_SETATTRS(attrs, CKA_VALUE, emailProfile->data,
                      emailProfile->len);
        attrs++;
    }
    realSize = attrs - theTemplate;
    PORT_Assert(realSize <= tsize);

    if (slot == NULL) {
        free_slot = slot = PK11_GetInternalKeySlot();
        /* we need to free the key slot in the end!!! */
    }

    rwsession = PK11_GetRWSession(slot);
    if (rwsession == CK_INVALID_SESSION) {
        PORT_SetError(SEC_ERROR_READ_ONLY);
        if (free_slot) {
            PK11_FreeSlot(free_slot);
        }
        return SECFailure;
    }

    crv = PK11_GETTAB(slot)->C_CreateObject(rwsession, theTemplate, realSize, &smimeh);
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
    }

    PK11_RestoreROSession(slot, rwsession);

    if (free_slot) {
        PK11_FreeSlot(free_slot);
    }
    return SECSuccess;
}

CERTSignedCrl *crl_storeCRL(PK11SlotInfo *slot, char *url,
                            CERTSignedCrl *newCrl, SECItem *derCrl, int type);

/* import the CRL into the token */

CERTSignedCrl *
PK11_ImportCRL(PK11SlotInfo *slot, SECItem *derCRL, char *url,
               int type, void *wincx, PRInt32 importOptions, PLArenaPool *arena,
               PRInt32 decodeoptions)
{
    CERTSignedCrl *newCrl, *crl;
    SECStatus rv;
    CERTCertificate *caCert = NULL;

    newCrl = crl = NULL;

    do {
        newCrl = CERT_DecodeDERCrlWithFlags(arena, derCRL, type,
                                            decodeoptions);
        if (newCrl == NULL) {
            if (type == SEC_CRL_TYPE) {
                /* only promote error when the error code is too generic */
                if (PORT_GetError() == SEC_ERROR_BAD_DER)
                    PORT_SetError(SEC_ERROR_CRL_INVALID);
            } else {
                PORT_SetError(SEC_ERROR_KRL_INVALID);
            }
            break;
        }

        if (0 == (importOptions & CRL_IMPORT_BYPASS_CHECKS)) {
            CERTCertDBHandle *handle = CERT_GetDefaultCertDB();
            PR_ASSERT(handle != NULL);
            caCert = CERT_FindCertByName(handle,
                                         &newCrl->crl.derName);
            if (caCert == NULL) {
                PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
                break;
            }

            /* If caCert is a v3 certificate, make sure that it can be used for
               crl signing purpose */
            rv = CERT_CheckCertUsage(caCert, KU_CRL_SIGN);
            if (rv != SECSuccess) {
                break;
            }

            rv = CERT_VerifySignedData(&newCrl->signatureWrap, caCert,
                                       PR_Now(), wincx);
            if (rv != SECSuccess) {
                if (type == SEC_CRL_TYPE) {
                    PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE);
                } else {
                    PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE);
                }
                break;
            }
        }

        crl = crl_storeCRL(slot, url, newCrl, derCRL, type);

    } while (0);

    if (crl == NULL) {
        SEC_DestroyCrl(newCrl);
    }
    if (caCert) {
        CERT_DestroyCertificate(caCert);
    }
    return (crl);
}
