/* 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 PKIT_H
#include "pkit.h"
#endif /* PKIT_H */

#ifndef DEVM_H
#include "devm.h"
#endif /* DEVM_H */

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

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

#include "pk11func.h"
#include "secmodti.h"
#include "secerr.h"

NSS_IMPLEMENT nssSession *
nssSession_ImportNSS3Session(NSSArena *arenaOpt,
                             CK_SESSION_HANDLE session,
                             PZLock *lock, PRBool rw)
{
    nssSession *rvSession = NULL;
    if (session != CK_INVALID_SESSION) {
        rvSession = nss_ZNEW(arenaOpt, nssSession);
        if (rvSession) {
            rvSession->handle = session;
            rvSession->lock = lock;
            rvSession->ownLock = PR_FALSE;
            rvSession->isRW = rw;
        }
    }
    return rvSession;
}

NSS_IMPLEMENT nssSession *
nssSlot_CreateSession(
    NSSSlot *slot,
    NSSArena *arenaOpt,
    PRBool readWrite)
{
    nssSession *rvSession;

    if (!readWrite) {
        /* nss3hack version only returns rw swssions */
        return NULL;
    }
    rvSession = nss_ZNEW(arenaOpt, nssSession);
    if (!rvSession) {
        return (nssSession *)NULL;
    }

    rvSession->handle = PK11_GetRWSession(slot->pk11slot);
    if (rvSession->handle == CK_INVALID_HANDLE) {
        nss_ZFreeIf(rvSession);
        return NULL;
    }
    rvSession->isRW = PR_TRUE;
    rvSession->slot = slot;
    /*
     * The session doesn't need its own lock.  Here's why.
     * 1. If we are reusing the default RW session of the slot,
     *    the slot lock is already locked to protect the session.
     * 2. If the module is not thread safe, the slot (or rather
     *    module) lock is already locked.
     * 3. If the module is thread safe and we are using a new
     *    session, no higher-level lock has been locked and we
     *    would need a lock for the new session.  However, the
     *    current usage of the session is that it is always
     *    used and destroyed within the same function and never
     *    shared with another thread.
     * So the session is either already protected by another
     * lock or only used by one thread.
     */
    rvSession->lock = NULL;
    rvSession->ownLock = PR_FALSE;
    return rvSession;
}

NSS_IMPLEMENT PRStatus
nssSession_Destroy(nssSession *s)
{
    PRStatus rv = PR_SUCCESS;
    if (s) {
        if (s->isRW) {
            PK11_RestoreROSession(s->slot->pk11slot, s->handle);
        }
        rv = nss_ZFreeIf(s);
    }
    return rv;
}

static NSSSlot *
nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
{
    NSSSlot *rvSlot;
    NSSArena *arena;
    arena = nssArena_Create();
    if (!arena) {
        return NULL;
    }
    rvSlot = nss_ZNEW(arena, NSSSlot);
    if (!rvSlot) {
        nssArena_Destroy(arena);
        return NULL;
    }
    rvSlot->base.refCount = 1;
    rvSlot->base.lock = PZ_NewLock(nssILockOther);
    rvSlot->base.arena = arena;
    rvSlot->pk11slot = PK11_ReferenceSlot(nss3slot);
    rvSlot->epv = nss3slot->functionList;
    rvSlot->slotID = nss3slot->slotID;
    /* Grab the slot name from the PKCS#11 fixed-length buffer */
    rvSlot->base.name = nssUTF8_Duplicate(nss3slot->slot_name, td->arena);
    rvSlot->lock = (nss3slot->isThreadSafe) ? NULL : nss3slot->sessionLock;
    rvSlot->isPresentLock = PZ_NewLock(nssiLockOther);
    rvSlot->isPresentCondition = PR_NewCondVar(rvSlot->isPresentLock);
    rvSlot->isPresentThread = NULL;
    rvSlot->lastTokenPingState = nssSlotLastPingState_Reset;
    return rvSlot;
}

NSSToken *
nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
{
    NSSToken *rvToken;
    NSSArena *arena;

    /* Don't create a token object for a disabled slot */
    if (nss3slot->disabled) {
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        return NULL;
    }
    arena = nssArena_Create();
    if (!arena) {
        return NULL;
    }
    rvToken = nss_ZNEW(arena, NSSToken);
    if (!rvToken) {
        nssArena_Destroy(arena);
        return NULL;
    }
    rvToken->base.refCount = 1;
    rvToken->base.lock = PZ_NewLock(nssILockOther);
    if (!rvToken->base.lock) {
        nssArena_Destroy(arena);
        return NULL;
    }
    rvToken->base.arena = arena;
    rvToken->pk11slot = PK11_ReferenceSlot(nss3slot);
    rvToken->epv = nss3slot->functionList;
    rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena,
                                                           nss3slot->session,
                                                           nss3slot->sessionLock,
                                                           nss3slot->defRWSession);
#if 0 /* we should do this instead of blindly continuing. */
    if (!rvToken->defaultSession) {
    PORT_SetError(SEC_ERROR_NO_TOKEN);
        goto loser;
    }
#endif
    if (!PK11_IsInternal(nss3slot) && PK11_IsHW(nss3slot)) {
        rvToken->cache = nssTokenObjectCache_Create(rvToken,
                                                    PR_TRUE, PR_TRUE, PR_TRUE);
        if (!rvToken->cache)
            goto loser;
    }
    rvToken->trustDomain = td;
    /* Grab the token name from the PKCS#11 fixed-length buffer */
    rvToken->base.name = nssUTF8_Duplicate(nss3slot->token_name, td->arena);
    rvToken->slot = nssSlot_CreateFromPK11SlotInfo(td, nss3slot);
    if (!rvToken->slot) {
        goto loser;
    }
    rvToken->slot->token = rvToken;
    if (rvToken->defaultSession)
        rvToken->defaultSession->slot = rvToken->slot;
    return rvToken;
loser:
    PZ_DestroyLock(rvToken->base.lock);
    nssArena_Destroy(arena);
    return NULL;
}

NSS_IMPLEMENT void
nssToken_UpdateName(NSSToken *token)
{
    if (!token) {
        return;
    }
    token->base.name = nssUTF8_Duplicate(token->pk11slot->token_name, token->base.arena);
}

NSS_IMPLEMENT PRBool
nssSlot_IsPermanent(NSSSlot *slot)
{
    return slot->pk11slot->isPerm;
}

NSS_IMPLEMENT PRBool
nssSlot_IsFriendly(NSSSlot *slot)
{
    return PK11_IsFriendly(slot->pk11slot);
}

NSS_IMPLEMENT PRStatus
nssToken_Refresh(NSSToken *token)
{
    PK11SlotInfo *nss3slot;

    if (!token) {
        return PR_SUCCESS;
    }
    nss3slot = token->pk11slot;
    token->defaultSession =
        nssSession_ImportNSS3Session(token->slot->base.arena,
                                     nss3slot->session,
                                     nss3slot->sessionLock,
                                     nss3slot->defRWSession);
    return token->defaultSession ? PR_SUCCESS : PR_FAILURE;
}

NSS_IMPLEMENT PRStatus
nssSlot_Refresh(NSSSlot *slot)
{
    PK11SlotInfo *nss3slot = slot->pk11slot;
    PRBool doit = PR_FALSE;
    if (slot->token && slot->token->base.name[0] == 0) {
        doit = PR_TRUE;
    }
    if (PK11_InitToken(nss3slot, PR_FALSE) != SECSuccess) {
        return PR_FAILURE;
    }
    if (doit) {
        nssTrustDomain_UpdateCachedTokenCerts(slot->token->trustDomain,
                                              slot->token);
    }
    return nssToken_Refresh(slot->token);
}

NSS_IMPLEMENT PRStatus
nssToken_GetTrustOrder(NSSToken *tok)
{
    PK11SlotInfo *slot;
    SECMODModule *module;
    slot = tok->pk11slot;
    module = PK11_GetModule(slot);
    return module->trustOrder;
}

NSS_IMPLEMENT PRBool
nssSlot_IsLoggedIn(NSSSlot *slot)
{
    if (!slot->pk11slot->needLogin) {
        return PR_TRUE;
    }
    return PK11_IsLoggedIn(slot->pk11slot, NULL);
}

NSSTrustDomain *
nssToken_GetTrustDomain(NSSToken *token)
{
    return token->trustDomain;
}

NSS_EXTERN PRStatus
nssTrustDomain_RemoveTokenCertsFromCache(
    NSSTrustDomain *td,
    NSSToken *token);

NSS_IMPLEMENT PRStatus
nssToken_NotifyCertsNotVisible(
    NSSToken *tok)
{
    return nssTrustDomain_RemoveTokenCertsFromCache(tok->trustDomain, tok);
}
