summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrelyea%netscape.com <devnull@localhost>2005-09-29 23:45:56 +0000
committerrelyea%netscape.com <devnull@localhost>2005-09-29 23:45:56 +0000
commitea64113e6806c36b0aa6ac379c23c0a42c135665 (patch)
treef98e9b766f6a36121ea4105931da217e19e16c5f
parent64db22fd8ef36f34ebfdc7245658982adb06edf9 (diff)
downloadnss-hg-ea64113e6806c36b0aa6ac379c23c0a42c135665.tar.gz
Bug 119500 PKCS#11 CKF_PROTECTED_AUTHENTICATION_PATH token flag not supported
r=wtc, r=nelson
-rw-r--r--security/nss/lib/pk11wrap/pk11auth.c63
-rw-r--r--security/nss/lib/pk11wrap/secmodt.h17
2 files changed, 75 insertions, 5 deletions
diff --git a/security/nss/lib/pk11wrap/pk11auth.c b/security/nss/lib/pk11wrap/pk11auth.c
index 18dc08806..a9bc39943 100644
--- a/security/nss/lib/pk11wrap/pk11auth.c
+++ b/security/nss/lib/pk11wrap/pk11auth.c
@@ -80,7 +80,7 @@ static struct PK11GlobalStruct {
SECStatus
pk11_CheckPassword(PK11SlotInfo *slot,char *pw)
{
- int len = PORT_Strlen(pw);
+ int len = 0;
CK_RV crv;
SECStatus rv;
int64 currtime = PR_Now();
@@ -88,6 +88,11 @@ pk11_CheckPassword(PK11SlotInfo *slot,char *pw)
if (slot->protectedAuthPath) {
len = 0;
pw = NULL;
+ } else if (pw == NULL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ } else {
+ len = PORT_Strlen(pw);
}
PK11_EnterSlotMonitor(slot);
@@ -121,7 +126,7 @@ pk11_CheckPassword(PK11SlotInfo *slot,char *pw)
SECStatus
PK11_CheckUserPassword(PK11SlotInfo *slot,char *pw)
{
- int len = PORT_Strlen(pw);
+ int len = 0;
CK_RV crv;
SECStatus rv;
int64 currtime = PR_Now();
@@ -129,6 +134,11 @@ PK11_CheckUserPassword(PK11SlotInfo *slot,char *pw)
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 */
@@ -312,15 +322,23 @@ PK11_CheckSSOPassword(PK11SlotInfo *slot, char *ssopw)
CK_SESSION_HANDLE rwsession;
CK_RV crv;
SECStatus rv = SECFailure;
- int len = PORT_Strlen(ssopw);
+ int len = 0;
/* get a rwsession */
rwsession = PK11_GetRWSession(slot);
- if (rwsession == CK_INVALID_SESSION) return rv;
+ if (rwsession == CK_INVALID_SESSION) {
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return rv;
+ }
if (slot->protectedAuthPath) {
len = 0;
ssopw = NULL;
+ } else if (ssopw == NULL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ } else {
+ len = PORT_Strlen(ssopw);
}
/* check the password */
@@ -383,7 +401,11 @@ PK11_InitPin(PK11SlotInfo *slot,char *ssopw, char *userpw)
/* get a rwsession */
rwsession = PK11_GetRWSession(slot);
- if (rwsession == CK_INVALID_SESSION) goto done;
+ if (rwsession == CK_INVALID_SESSION) {
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ slot->lastLoginCheck = 0;
+ return rv;
+ }
if (slot->protectedAuthPath) {
len = 0;
@@ -443,6 +465,10 @@ PK11_ChangePW(PK11SlotInfo *slot,char *oldpw, char *newpw)
/* get a rwsession */
rwsession = PK11_GetRWSession(slot);
+ if (rwsession == CK_INVALID_SESSION) {
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return rv;
+ }
crv = PK11_GETTAB(slot)->C_SetPIN(rwsession,
(unsigned char *)oldpw,oldLen,(unsigned char *)newpw,newLen);
@@ -534,7 +560,34 @@ PK11_DoPassword(PK11SlotInfo *slot, PRBool loadCerts, void *wincx)
* (3) the password was successful.
*/
while ((password = pk11_GetPassword(slot, attempt, wincx)) != NULL) {
+ /* if the token has a protectedAuthPath, the application may have
+ * already issued the C_Login as part of it's pk11_GetPassword call.
+ * In this case the application will tell us what the results were in
+ * the password value (retry or the authentication was successful) so
+ * we can skip our own C_Login call (which would force the token to
+ * try to login again).
+ *
+ * Applications that don't know about protectedAuthPath will return a
+ * password, which we will ignore and trigger the token to
+ * 'authenticate' itself anyway. Hopefully the blinking display on
+ * the reader, or the flashing light under the thumbprint reader will
+ * attract the user's attention */
attempt = PR_TRUE;
+ if (slot->protectedAuthPath) {
+ /* application tried to authenticate and failed. it wants to try
+ * again, continue looping */
+ if (strcmp(password, PK11_PW_RETRY) == 0) {
+ rv = SECWouldBlock;
+ PORT_Free(password);
+ continue;
+ }
+ /* applicaton tried to authenticate and succeeded we're done */
+ if (strcmp(password, PK11_PW_AUTHENTICATED) == 0) {
+ rv = SECSuccess;
+ PORT_Free(password);
+ break;
+ }
+ }
rv = pk11_CheckPassword(slot,password);
PORT_Memset(password, 0, PORT_Strlen(password));
PORT_Free(password);
diff --git a/security/nss/lib/pk11wrap/secmodt.h b/security/nss/lib/pk11wrap/secmodt.h
index 9114ce1f8..cc63eddc7 100644
--- a/security/nss/lib/pk11wrap/secmodt.h
+++ b/security/nss/lib/pk11wrap/secmodt.h
@@ -389,6 +389,23 @@ typedef PRBool (PR_CALLBACK *PK11VerifyPasswordFunc)(PK11SlotInfo *slot, void *a
typedef PRBool (PR_CALLBACK *PK11IsLoggedInFunc)(PK11SlotInfo *slot, void *arg);
/*
+ * Special strings the password callback function can return only if
+ * the slot is an protected auth path slot.
+ */
+#define PK11_PW_RETRY "RETRY" /* an failed attempt to authenticate
+ * has already been made, just retry
+ * the operation */
+#define PK11_PW_AUTHENTICATED "AUTH" /* a successful attempt to authenticate
+ * has completed. Continue without
+ * another call to C_Login */
+/* All other non-null values mean that that NSS could call C_Login to force
+ * the authentication. The following define is to aid applications in
+ * documenting that is what it's trying to do */
+#define PK11_PW_TRY "TRY" /* Default: a prompt has been presented
+ * to the user, initiate a C_Login
+ * to authenticate the token */
+
+/*
* PKCS #11 key structures
*/