summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrelyea%netscape.com <devnull@localhost>2002-12-11 17:43:24 +0000
committerrelyea%netscape.com <devnull@localhost>2002-12-11 17:43:24 +0000
commit0d6277e29895f70f6ab0c16734175be6e4560d75 (patch)
treeb91384d5e941d15d7662134393011780f9c9d3c1
parent80908b1ec4a5bff5002b4ff383016acc268402cb (diff)
downloadnss-hg-0d6277e29895f70f6ab0c16734175be6e4560d75.tar.gz
Add token removal blocking function.
-rw-r--r--security/nss/lib/pk11wrap/pk11func.h30
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c50
-rw-r--r--security/nss/lib/pk11wrap/secmodt.h15
3 files changed, 94 insertions, 1 deletions
diff --git a/security/nss/lib/pk11wrap/pk11func.h b/security/nss/lib/pk11wrap/pk11func.h
index 37f101237..0a450659c 100644
--- a/security/nss/lib/pk11wrap/pk11func.h
+++ b/security/nss/lib/pk11wrap/pk11func.h
@@ -165,6 +165,36 @@ PRBool PK11_UserDisableSlot(PK11SlotInfo *slot);
/* Allow all mechanisms that are ON before UserDisableSlot() */
/* was called to be available again */
PRBool PK11_UserEnableSlot(PK11SlotInfo *slot);
+/*
+ * wait for a specific slot event.
+ * event is a specific event to wait for. Currently only
+ * PK11TokenChangeOrRemovalEvent and PK11TokenPresentEvents are defined.
+ * timeout can be an interval time to wait, PR_INTERVAL_NO_WAIT (meaning only
+ * poll once), or PR_INTERVAL_NO_TIMEOUT (meaning block until a change).
+ * pollInterval is a suggested pulling interval value. '0' means use the
+ * default. Future implementations that don't poll may ignore this value.
+ * series is the current series for the last slot. This should be the series
+ * value for the slot the last time you read persistant information from the
+ * slot. For instance, if you publish a cert from the slot, you should obtain
+ * the slot series at that time. Then PK11_WaitForTokenEvent can detect a
+ * a change in the slot between the time you publish and the time
+ * PK11_WaitForTokenEvent is called, elliminating potential race conditions.
+ *
+ * The current status that is returned is:
+ * PK11TokenNotRemovable - always returned for any non-removable token.
+ * PK11TokenPresent - returned when the token is present and we are waiting
+ * on a PK11TokenPresentEvent. Then next event to look for is a
+ * PK11TokenChangeOrRemovalEvent.
+ * PK11TokenChanged - returned when the old token has been removed and a new
+ * token ad been inserted, and we are waiting for a
+ * PK11TokenChangeOrRemovalEvent. The next event to look for is another
+ * PK11TokenChangeOrRemovalEvent.
+ * PK11TokenRemoved - returned when the token is not present and we are
+ * waiting for a PK11TokenChangeOrRemovalEvent. The next event to look for
+ * is a PK11TokenPresentEvent.
+ */
+PK11TokenStatus PK11_WaitForTokenEvent(PK11SlotInfo *slot, PK11TokenEvent event,
+ PRIntervalTime timeout, PRIntervalTime pollInterval, int series);
PRBool PK11_NeedPWInit(void);
PRBool PK11_NeedPWInitForSlot(PK11SlotInfo *slot);
diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c
index a4dec80e3..c87e9400b 100644
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -419,7 +419,7 @@ PK11_NewSlotInfo(void)
slot->isInternal = PR_FALSE;
slot->isThreadSafe = PR_FALSE;
slot->disabled = PR_FALSE;
- slot->series = 0;
+ slot->series = 1;
slot->wrapKey = 0;
slot->wrapMechanism = CKM_INVALID_MECHANISM;
slot->refKeys[0] = CK_INVALID_HANDLE;
@@ -4606,3 +4606,51 @@ PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
}
return SECSuccess;
}
+
+/*
+ * wait for a token to change it's state. The application passes in the expected
+ * new state in event.
+ */
+PK11TokenStatus
+PK11_WaitForTokenEvent(PK11SlotInfo *slot, PK11TokenEvent event,
+ PRIntervalTime timeout, PRIntervalTime latency, int series)
+{
+ PRIntervalTime first_time = 0;
+ PRBool first_time_set = PR_FALSE;
+ PRBool waitForRemoval;
+
+ if (slot->isPerm) {
+ return PK11TokenNotRemovable;
+ }
+ if (latency == 0) {
+ latency = PR_SecondsToInterval(5);
+ }
+ waitForRemoval = (PRBool) (event == PK11TokenRemovedOrChangedEvent);
+
+ if (series == 0) {
+ series = PK11_GetSlotSeries(slot);
+ }
+ while (PK11_IsPresent(slot) == waitForRemoval ) {
+ PRIntervalTime interval;
+
+ if (waitForRemoval && series != PK11_GetSlotSeries(slot)) {
+ return PK11TokenChanged;
+ }
+ if (timeout == PR_INTERVAL_NO_WAIT) {
+ return waitForRemoval ? PK11TokenPresent : PK11TokenRemoved;
+ }
+ if (timeout == PR_INTERVAL_NO_TIMEOUT ) {
+ interval = PR_IntervalNow();
+ if (!first_time_set) {
+ first_time = interval;
+ first_time_set = PR_TRUE;
+ }
+ if ((interval-first_time) > timeout) {
+ return waitForRemoval ? PK11TokenPresent : PK11TokenRemoved;
+ }
+ }
+ PR_Sleep(latency);
+ }
+ return waitForRemoval ? PK11TokenRemoved : PK11TokenPresent;
+}
+
diff --git a/security/nss/lib/pk11wrap/secmodt.h b/security/nss/lib/pk11wrap/secmodt.h
index b83f57d63..919d3bca3 100644
--- a/security/nss/lib/pk11wrap/secmodt.h
+++ b/security/nss/lib/pk11wrap/secmodt.h
@@ -245,4 +245,19 @@ struct SECKEYEncryptedPrivateKeyInfoStr {
};
typedef struct SECKEYEncryptedPrivateKeyInfoStr SECKEYEncryptedPrivateKeyInfo;
+/*
+ * token removal detection
+ */
+typedef enum {
+ PK11TokenNotRemovable = 0,
+ PK11TokenPresent = 1,
+ PK11TokenChanged = 2,
+ PK11TokenRemoved = 3
+} PK11TokenStatus;
+
+typedef enum {
+ PK11TokenRemovedOrChangedEvent = 0,
+ PK11TokenPresentEvent = 1
+} PK11TokenEvent;
+
#endif /*_SECMODT_H_ */