/* 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_HANDLE) {
        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);
}
