diff options
author | relyea%netscape.com <devnull@localhost> | 2002-12-11 17:43:24 +0000 |
---|---|---|
committer | relyea%netscape.com <devnull@localhost> | 2002-12-11 17:43:24 +0000 |
commit | 0d6277e29895f70f6ab0c16734175be6e4560d75 (patch) | |
tree | b91384d5e941d15d7662134393011780f9c9d3c1 | |
parent | 80908b1ec4a5bff5002b4ff383016acc268402cb (diff) | |
download | nss-hg-0d6277e29895f70f6ab0c16734175be6e4560d75.tar.gz |
Add token removal blocking function.
-rw-r--r-- | security/nss/lib/pk11wrap/pk11func.h | 30 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11slot.c | 50 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/secmodt.h | 15 |
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_ */ |