Пример #1
0
/*
 * before we do a private key op, we check to see if we
 * need to reauthenticate.
 */
void
PK11_HandlePasswordCheck(PK11SlotInfo *slot,void *wincx)
{
    int askpw = slot->askpw;
    PRBool NeedAuth = PR_FALSE;

    if (!slot->needLogin) return;

    if ((slot->defaultFlags & PK11_OWN_PW_DEFAULTS) == 0) {
	PK11SlotInfo *def_slot = PK11_GetInternalKeySlot();

	if (def_slot) {
	    askpw = def_slot->askpw;
	    PK11_FreeSlot(def_slot);
	}
    }

    /* timeouts are handled by isLoggedIn */
    if (!PK11_IsLoggedIn(slot,wincx)) {
	NeedAuth = PR_TRUE;
    } else if (askpw == -1) {
	if (!PK11_Global.inTransaction	||
			 (PK11_Global.transaction != slot->authTransact)) {
    	    PK11_EnterSlotMonitor(slot);
	    PK11_GETTAB(slot)->C_Logout(slot->session);
	    slot->lastLoginCheck = 0;
    	    PK11_ExitSlotMonitor(slot);
	    NeedAuth = PR_TRUE;
	}
    }
    if (NeedAuth) PK11_DoPassword(slot,PR_TRUE,wincx);
}
Пример #2
0
/*
 * Check the user's password. Logout before hand to make sure that
 * we are really checking the password.
 */
SECStatus
PK11_CheckUserPassword(PK11SlotInfo *slot, const char *pw)
{
    int len = 0;
    CK_RV crv;
    SECStatus rv;
    int64 currtime = PR_Now();

    if (slot->protectedAuthPath) {
	len = 0;
	pw = NULL;
    } else if (pw == NULL) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    } else {
	len = PORT_Strlen(pw);
    }

    /*
     * If the token does't need a login, don't try to relogin beause the
     * effect is undefined. It's not clear what it means to check a non-empty
     * password with such a token, so treat that as an error.
     */
    if (!slot->needLogin) {
        if (len == 0) {
            rv = SECSuccess;
        } else {
            PORT_SetError(SEC_ERROR_BAD_PASSWORD);
            rv = SECFailure;
        }
        return rv;
    }

    /* force a logout */
    PK11_EnterSlotMonitor(slot);
    PK11_GETTAB(slot)->C_Logout(slot->session);

    crv = PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER,
					(unsigned char *)pw,len);
    slot->lastLoginCheck = 0;
    PK11_ExitSlotMonitor(slot);
    switch (crv) {
    /* if we're already logged in, we're good to go */
    case CKR_OK:
	slot->authTransact = PK11_Global.transaction;
	slot->authTime = currtime;
	rv = SECSuccess;
	break;
    case CKR_PIN_INCORRECT:
	PORT_SetError(SEC_ERROR_BAD_PASSWORD);
	rv = SECWouldBlock; /* everything else is ok, only the pin is bad */
	break;
    default:
	PORT_SetError(PK11_MapError(crv));
	rv = SECFailure; /* some failure we can't fix by retrying */
    }
    return rv;
}
Пример #3
0
/*
 * the monitors...
 */
void
PK11_EnterContextMonitor(PK11Context *cx) {
    /* if we own the session and our slot is ThreadSafe, only monitor
     * the Context */
    if ((cx->ownSession) && (cx->slot->isThreadSafe)) {
        /* Should this use monitors instead? */
        PZ_Lock(cx->sessionLock);
    } else {
        PK11_EnterSlotMonitor(cx->slot);
    }
}
Пример #4
0
SECStatus
PK11_Logout(PK11SlotInfo *slot)
{
    CK_RV crv;

    /* force a logout */
    PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_Logout(slot->session);
    slot->lastLoginCheck = 0;
    PK11_ExitSlotMonitor(slot);
    if (crv != CKR_OK) {
	PORT_SetError(PK11_MapError(crv));
	return SECFailure;
    }
    return  SECSuccess;
}
Пример #5
0
/*
 * Determine if the token is logged in. We have to actually query the token,
 * because it's state can change without intervention from us.
 */
PRBool
PK11_IsLoggedIn(PK11SlotInfo *slot,void *wincx)
{
    CK_SESSION_INFO sessionInfo;
    int askpw = slot->askpw;
    int timeout = slot->timeout;
    CK_RV crv;
    PRIntervalTime curTime;
    static PRIntervalTime login_delay_time = 0;

    if (login_delay_time == 0) {
	login_delay_time = PR_SecondsToInterval(1);
    }

    /* If we don't have our own password default values, use the system
     * ones */
    if ((slot->defaultFlags & PK11_OWN_PW_DEFAULTS) == 0) {
	PK11SlotInfo *def_slot = PK11_GetInternalKeySlot();

	if (def_slot) {
	    askpw = def_slot->askpw;
	    timeout = def_slot->timeout;
	    PK11_FreeSlot(def_slot);
	}
    }

    if ((wincx != NULL) && (PK11_Global.isLoggedIn != NULL) &&
	(*PK11_Global.isLoggedIn)(slot, wincx) == PR_FALSE) { return PR_FALSE; }


    /* forget the password if we've been inactive too long */
    if (askpw == 1) {
	int64 currtime = PR_Now();
	int64 result;
	int64 mult;
	
	LL_I2L(result, timeout);
	LL_I2L(mult, 60*1000*1000);
	LL_MUL(result,result,mult);
	LL_ADD(result, result, slot->authTime);
	if (LL_CMP(result, <, currtime) ) {
	    PK11_EnterSlotMonitor(slot);
	    PK11_GETTAB(slot)->C_Logout(slot->session);
	    slot->lastLoginCheck = 0;
	    PK11_ExitSlotMonitor(slot);
	} else {
Пример #6
0
/*
 * Check the user's password. Logout before hand to make sure that
 * we are really checking the password.
 */
SECStatus
PK11_CheckUserPassword(PK11SlotInfo *slot, const char *pw)
{
    int len = 0;
    CK_RV crv;
    SECStatus rv;
    int64 currtime = PR_Now();

    if (slot->protectedAuthPath) {
	len = 0;
	pw = NULL;
    } else if (pw == NULL) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    } else {
	len = PORT_Strlen(pw);
    }

    /* force a logout */
    PK11_EnterSlotMonitor(slot);
    PK11_GETTAB(slot)->C_Logout(slot->session);

    crv = PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER,
					(unsigned char *)pw,len);
    slot->lastLoginCheck = 0;
    PK11_ExitSlotMonitor(slot);
    switch (crv) {
    /* if we're already logged in, we're good to go */
    case CKR_OK:
	slot->authTransact = PK11_Global.transaction;
	slot->authTime = currtime;
	rv = SECSuccess;
	break;
    case CKR_PIN_INCORRECT:
	PORT_SetError(SEC_ERROR_BAD_PASSWORD);
	rv = SECWouldBlock; /* everything else is ok, only the pin is bad */
	break;
    default:
	PORT_SetError(PK11_MapError(crv));
	rv = SECFailure; /* some failure we can't fix by retrying */
    }
    return rv;
}
Пример #7
0
static void
pk11_EnterKeyMonitor(PK11SymKey *symKey) {
    if (!symKey->sessionOwner || !(symKey->slot->isThreadSafe)) 
	PK11_EnterSlotMonitor(symKey->slot);
}
Пример #8
0
/*
 * Check the user's password. Log into the card if it's correct.
 * succeed if the user is already logged in.
 */
SECStatus
pk11_CheckPassword(PK11SlotInfo *slot,char *pw)
{
    int len = 0;
    CK_RV crv;
    SECStatus rv;
    int64 currtime = PR_Now();
    PRBool mustRetry;
    int retry = 0;

    if (slot->protectedAuthPath) {
	len = 0;
	pw = NULL;
    } else if (pw == NULL) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    } else {
	len = PORT_Strlen(pw);
    }

    do {
	PK11_EnterSlotMonitor(slot);
	crv = PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER,
						(unsigned char *)pw,len);
	slot->lastLoginCheck = 0;
	mustRetry = PR_FALSE;
	PK11_ExitSlotMonitor(slot);
	switch (crv) {
	/* if we're already logged in, we're good to go */
	case CKR_OK:
	    slot->authTransact = PK11_Global.transaction;
	    /* Fall through */
	case CKR_USER_ALREADY_LOGGED_IN:
	    slot->authTime = currtime;
	    rv = SECSuccess;
	    break;
	case CKR_PIN_INCORRECT:
	    PORT_SetError(SEC_ERROR_BAD_PASSWORD);
	    rv = SECWouldBlock; /* everything else is ok, only the pin is bad */
	    break;
	/* someone called reset while we fetched the password, try again once
	 * if the token is still there. */
	case CKR_SESSION_HANDLE_INVALID:
	case CKR_SESSION_CLOSED:
	    if (retry++ == 0) {
		rv = PK11_InitToken(slot,PR_FALSE);
		if (rv == SECSuccess) {
		    if (slot->session != CK_INVALID_SESSION) {
			mustRetry = PR_TRUE;
		    } else {
			PORT_SetError(PK11_MapError(crv));
			rv = SECFailure;
		    }
		}
		break;
	    }
	    /* Fall through */
	default:
	    PORT_SetError(PK11_MapError(crv));
	    rv = SECFailure; /* some failure we can't fix by retrying */
	}
    } while (mustRetry);
    return rv;
}
Пример #9
0
/*
 * initialize a user PIN Value
 */
SECStatus
PK11_InitPin(PK11SlotInfo *slot, const char *ssopw, const char *userpw)
{
    CK_SESSION_HANDLE rwsession = CK_INVALID_SESSION;
    CK_RV crv;
    SECStatus rv = SECFailure;
    int len;
    int ssolen;

    if (userpw == NULL) userpw = "";
    if (ssopw == NULL) ssopw = "";

    len = PORT_Strlen(userpw);
    ssolen = PORT_Strlen(ssopw);

    /* get a rwsession */
    rwsession = PK11_GetRWSession(slot);
    if (rwsession == CK_INVALID_SESSION) {
    	PORT_SetError(SEC_ERROR_BAD_DATA);
	slot->lastLoginCheck = 0;
    	return rv;
    }

    if (slot->protectedAuthPath) {
	len = 0;
	ssolen = 0;
	ssopw = NULL;
	userpw = NULL;
    }

    /* check the password */
    crv = PK11_GETTAB(slot)->C_Login(rwsession,CKU_SO, 
					  (unsigned char *)ssopw,ssolen);
    slot->lastLoginCheck = 0;
    if (crv != CKR_OK) {
	PORT_SetError(PK11_MapError(crv));
	goto done;
    }

    crv = PK11_GETTAB(slot)->C_InitPIN(rwsession,(unsigned char *)userpw,len);
    if (crv != CKR_OK) {
	PORT_SetError(PK11_MapError(crv));
    } else {
    	rv = SECSuccess;
    }

done:
    PK11_GETTAB(slot)->C_Logout(rwsession);
    slot->lastLoginCheck = 0;
    PK11_RestoreROSession(slot,rwsession);
    if (rv == SECSuccess) {
        /* update our view of the world */
        PK11_InitToken(slot,PR_TRUE);
	if (slot->needLogin) {
	    PK11_EnterSlotMonitor(slot);
	    PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER,
						(unsigned char *)userpw,len);
	    slot->lastLoginCheck = 0;
	    PK11_ExitSlotMonitor(slot);
	}
    }
    return rv;
}
/*
 * Check the user's password. Log into the card if it's correct.
 * succeed if the user is already logged in.
 */
static SECStatus
pk11_CheckPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
			char *pw, PRBool alreadyLocked, PRBool contextSpecific)
{
    int len = 0;
    CK_RV crv;
    SECStatus rv;
    int64 currtime = PR_Now();
    PRBool mustRetry;
    int retry = 0;

    if (slot->protectedAuthPath) {
	len = 0;
	pw = NULL;
    } else if (pw == NULL) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    } else {
	len = PORT_Strlen(pw);
    }

    do {
	if (!alreadyLocked) PK11_EnterSlotMonitor(slot);
	crv = PK11_GETTAB(slot)->C_Login(session,
		contextSpecific ? CKU_CONTEXT_SPECIFIC : CKU_USER,
						(unsigned char *)pw,len);
	slot->lastLoginCheck = 0;
	mustRetry = PR_FALSE;
	if (!alreadyLocked) PK11_ExitSlotMonitor(slot);
	switch (crv) {
	/* if we're already logged in, we're good to go */
	case CKR_OK:
		/* TODO If it was for CKU_CONTEXT_SPECIFIC should we do this */
	    slot->authTransact = PK11_Global.transaction;
	    /* Fall through */
	case CKR_USER_ALREADY_LOGGED_IN:
	    slot->authTime = currtime;
	    rv = SECSuccess;
	    break;
	case CKR_PIN_INCORRECT:
	    PORT_SetError(SEC_ERROR_BAD_PASSWORD);
	    rv = SECWouldBlock; /* everything else is ok, only the pin is bad */
	    break;
	/* someone called reset while we fetched the password, try again once
	 * if the token is still there. */
	case CKR_SESSION_HANDLE_INVALID:
	case CKR_SESSION_CLOSED:
	    if (session != slot->session) {
		/* don't bother retrying, we were in a middle of an operation,
		 * which is now lost. Just fail. */
	        PORT_SetError(PK11_MapError(crv));
	        rv = SECFailure; 
		break;
	    }
	    if (retry++ == 0) {
		rv = PK11_InitToken(slot,PR_FALSE);
		if (rv == SECSuccess) {
		    if (slot->session != CK_INVALID_SESSION) {
			session = slot->session; /* we should have 
						  * a new session now */
			mustRetry = PR_TRUE;
		    } else {
			PORT_SetError(PK11_MapError(crv));
			rv = SECFailure;
		    }
		}
		break;
	    }
	    /* Fall through */
	default:
	    PORT_SetError(PK11_MapError(crv));
	    rv = SECFailure; /* some failure we can't fix by retrying */
	}
    } while (mustRetry);
    return rv;
}