Skip to content

Commit 418b23c

Browse files
author
Lars Silvén
committed
Do not refresh object store before fetching object.
Before this commit the object store for a file token was always refreshed by reading the file of the token every time an object of the token was fetched. Now the HSM may be configured not to refresh when fetching an object. But the refresh will still be done after an application gets a handle for an object. The reason for this change is that the CPU time consumed by the reading may not be negligible for some HW.
1 parent 28c67fe commit 418b23c

14 files changed

+79
-36
lines changed

src/lib/SoftHSM.cpp

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,8 @@ CK_RV SoftHSM::C_Initialize(CK_VOID_PTR pInitArgs)
609609
// Load the handle manager
610610
handleManager = new HandleManager();
611611

612+
doRefresh = Configuration::i()->getBool("objectstore.readrefresh", true);
613+
612614
// Set the state to initialised
613615
isInitialised = true;
614616

@@ -1605,7 +1607,7 @@ CK_RV SoftHSM::C_CopyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject
16051607

16061608
// Check the object handle.
16071609
OSObject *object = (OSObject *)handleManager->getObject(hObject);
1608-
if (object == NULL_PTR || !object->isValid()) return CKR_OBJECT_HANDLE_INVALID;
1610+
if (object == NULL_PTR || !object->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
16091611

16101612
CK_BBOOL wasOnToken = object->getBooleanValue(CKA_TOKEN, false);
16111613
CK_BBOOL wasPrivate = object->getBooleanValue(CKA_PRIVATE, true);
@@ -1774,7 +1776,7 @@ CK_RV SoftHSM::C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObj
17741776

17751777
// Check the object handle.
17761778
OSObject *object = (OSObject *)handleManager->getObject(hObject);
1777-
if (object == NULL_PTR || !object->isValid()) return CKR_OBJECT_HANDLE_INVALID;
1779+
if (object == NULL_PTR || !object->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
17781780

17791781
CK_BBOOL isOnToken = object->getBooleanValue(CKA_TOKEN, false);
17801782
CK_BBOOL isPrivate = object->getBooleanValue(CKA_PRIVATE, true);
@@ -1822,7 +1824,7 @@ CK_RV SoftHSM::C_GetObjectSize(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObj
18221824

18231825
// Check the object handle.
18241826
OSObject *object = (OSObject *)handleManager->getObject(hObject);
1825-
if (object == NULL_PTR || !object->isValid()) return CKR_OBJECT_HANDLE_INVALID;
1827+
if (object == NULL_PTR || !object->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
18261828

18271829
*pulSize = CK_UNAVAILABLE_INFORMATION;
18281830

@@ -1846,7 +1848,7 @@ CK_RV SoftHSM::C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE
18461848

18471849
// Check the object handle.
18481850
OSObject *object = (OSObject *)handleManager->getObject(hObject);
1849-
if (object == NULL_PTR || !object->isValid()) return CKR_OBJECT_HANDLE_INVALID;
1851+
if (object == NULL_PTR || !object->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
18501852

18511853
CK_BBOOL isOnToken = object->getBooleanValue(CKA_TOKEN, false);
18521854
CK_BBOOL isPrivate = object->getBooleanValue(CKA_PRIVATE, true);
@@ -1893,7 +1895,7 @@ CK_RV SoftHSM::C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE
18931895

18941896
// Check the object handle.
18951897
OSObject *object = (OSObject *)handleManager->getObject(hObject);
1896-
if (object == NULL_PTR || !object->isValid()) return CKR_OBJECT_HANDLE_INVALID;
1898+
if (object == NULL_PTR || !object->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
18971899

18981900
CK_BBOOL isOnToken = object->getBooleanValue(CKA_TOKEN, false);
18991901
CK_BBOOL isPrivate = object->getBooleanValue(CKA_PRIVATE, true);
@@ -2163,7 +2165,7 @@ CK_RV SoftHSM::SymEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
21632165

21642166
// Check the key handle.
21652167
OSObject *key = (OSObject *)handleManager->getObject(hKey);
2166-
if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
2168+
if (key == NULL_PTR || !key->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
21672169

21682170
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
21692171
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -2411,7 +2413,7 @@ CK_RV SoftHSM::AsymEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMec
24112413

24122414
// Check the key handle.
24132415
OSObject *key = (OSObject *)handleManager->getObject(hKey);
2414-
if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
2416+
if (key == NULL_PTR || !key->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
24152417

24162418
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
24172419
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -2883,7 +2885,7 @@ CK_RV SoftHSM::SymDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
28832885

28842886
// Check the key handle.
28852887
OSObject *key = (OSObject *)handleManager->getObject(hKey);
2886-
if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
2888+
if (key == NULL_PTR || !key->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
28872889

28882890
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
28892891
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -3132,7 +3134,7 @@ CK_RV SoftHSM::AsymDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMec
31323134

31333135
// Check the key handle.
31343136
OSObject *key = (OSObject *)handleManager->getObject(hKey);
3135-
if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
3137+
if (key == NULL_PTR || !key->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
31363138

31373139
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
31383140
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -3775,7 +3777,7 @@ CK_RV SoftHSM::C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
37753777

37763778
// Check the key handle.
37773779
OSObject *key = (OSObject *)handleManager->getObject(hObject);
3778-
if (key == NULL_PTR || !key->isValid()) return CKR_KEY_HANDLE_INVALID;
3780+
if (key == NULL_PTR || !key->isValid(doRefresh)) return CKR_KEY_HANDLE_INVALID;
37793781

37803782
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
37813783
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -3926,7 +3928,7 @@ CK_RV SoftHSM::MacSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechani
39263928

39273929
// Check the key handle.
39283930
OSObject *key = (OSObject *)handleManager->getObject(hKey);
3929-
if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
3931+
if (key == NULL_PTR || !key->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
39303932

39313933
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
39323934
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -4078,7 +4080,7 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
40784080

40794081
// Check the key handle.
40804082
OSObject *key = (OSObject *)handleManager->getObject(hKey);
4081-
if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
4083+
if (key == NULL_PTR || !key->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
40824084

40834085
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
40844086
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -4904,7 +4906,7 @@ CK_RV SoftHSM::MacVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMecha
49044906

49054907
// Check the key handle.
49064908
OSObject *key = (OSObject *)handleManager->getObject(hKey);
4907-
if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
4909+
if (key == NULL_PTR || !key->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
49084910

49094911
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
49104912
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -5056,7 +5058,7 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
50565058

50575059
// Check the key handle.
50585060
OSObject *key = (OSObject *)handleManager->getObject(hKey);
5059-
if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
5061+
if (key == NULL_PTR || !key->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
50605062

50615063
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
50625064
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -6492,7 +6494,7 @@ CK_RV SoftHSM::C_WrapKey
64926494

64936495
// Check the wrapping key handle.
64946496
OSObject *wrapKey = (OSObject *)handleManager->getObject(hWrappingKey);
6495-
if (wrapKey == NULL_PTR || !wrapKey->isValid()) return CKR_WRAPPING_KEY_HANDLE_INVALID;
6497+
if (wrapKey == NULL_PTR || !wrapKey->isValid(doRefresh)) return CKR_WRAPPING_KEY_HANDLE_INVALID;
64966498

64976499
CK_BBOOL isWrapKeyOnToken = wrapKey->getBooleanValue(CKA_TOKEN, false);
64986500
CK_BBOOL isWrapKeyPrivate = wrapKey->getBooleanValue(CKA_PRIVATE, true);
@@ -6534,7 +6536,7 @@ CK_RV SoftHSM::C_WrapKey
65346536

65356537
// Check the to be wrapped key handle.
65366538
OSObject *key = (OSObject *)handleManager->getObject(hKey);
6537-
if (key == NULL_PTR || !key->isValid()) return CKR_KEY_HANDLE_INVALID;
6539+
if (key == NULL_PTR || !key->isValid(doRefresh)) return CKR_KEY_HANDLE_INVALID;
65386540

65396541
CK_BBOOL isKeyOnToken = key->getBooleanValue(CKA_TOKEN, false);
65406542
CK_BBOOL isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -6959,7 +6961,7 @@ CK_RV SoftHSM::C_UnwrapKey
69596961

69606962
// Check the unwrapping key handle.
69616963
OSObject *unwrapKey = (OSObject *)handleManager->getObject(hUnwrappingKey);
6962-
if (unwrapKey == NULL_PTR || !unwrapKey->isValid()) return CKR_UNWRAPPING_KEY_HANDLE_INVALID;
6964+
if (unwrapKey == NULL_PTR || !unwrapKey->isValid(doRefresh)) return CKR_UNWRAPPING_KEY_HANDLE_INVALID;
69636965

69646966
CK_BBOOL isUnwrapKeyOnToken = unwrapKey->getBooleanValue(CKA_TOKEN, false);
69656967
CK_BBOOL isUnwrapKeyPrivate = unwrapKey->getBooleanValue(CKA_PRIVATE, true);
@@ -7257,7 +7259,7 @@ CK_RV SoftHSM::C_DeriveKey
72577259

72587260
// Check the key handle.
72597261
OSObject *key = (OSObject *)handleManager->getObject(hBaseKey);
7260-
if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
7262+
if (key == NULL_PTR || !key->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
72617263

72627264
CK_BBOOL isKeyOnToken = key->getBooleanValue(CKA_TOKEN, false);
72637265
CK_BBOOL isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -10360,7 +10362,7 @@ CK_RV SoftHSM::deriveDH
1036010362

1036110363
// Get the base key handle
1036210364
OSObject *baseKey = (OSObject *)handleManager->getObject(hBaseKey);
10363-
if (baseKey == NULL || !baseKey->isValid())
10365+
if (baseKey == NULL || !baseKey->isValid(doRefresh))
1036410366
return CKR_KEY_HANDLE_INVALID;
1036510367

1036610368
// Get the DH algorithm handler
@@ -10692,7 +10694,7 @@ CK_RV SoftHSM::deriveECDH
1069210694

1069310695
// Get the base key handle
1069410696
OSObject *baseKey = (OSObject *)handleManager->getObject(hBaseKey);
10695-
if (baseKey == NULL || !baseKey->isValid())
10697+
if (baseKey == NULL || !baseKey->isValid(doRefresh))
1069610698
return CKR_KEY_HANDLE_INVALID;
1069710699

1069810700
// Get the ECDH algorithm handler
@@ -11046,7 +11048,7 @@ CK_RV SoftHSM::deriveEDDSA
1104611048

1104711049
// Get the base key handle
1104811050
OSObject *baseKey = (OSObject *)handleManager->getObject(hBaseKey);
11049-
if (baseKey == NULL || !baseKey->isValid())
11051+
if (baseKey == NULL || !baseKey->isValid(doRefresh))
1105011052
return CKR_KEY_HANDLE_INVALID;
1105111053

1105211054
// Get the EDDSA algorithm handler
@@ -11572,7 +11574,7 @@ CK_RV SoftHSM::deriveSymmetric
1157211574

1157311575
// Check the key handle
1157411576
OSObject *baseKey = (OSObject *)handleManager->getObject(hBaseKey);
11575-
if (baseKey == NULL_PTR || !baseKey->isValid()) return CKR_OBJECT_HANDLE_INVALID;
11577+
if (baseKey == NULL_PTR || !baseKey->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
1157611578

1157711579
// Get the data
1157811580
ByteString secretValue;

src/lib/SoftHSM.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ class SoftHSM
186186
// Is the SoftHSM PKCS #11 library initialised?
187187
bool isInitialised;
188188
bool isRemovable;
189+
// Do refresh of all objects from storage before validating.
190+
bool doRefresh;
189191

190192
SessionObjectStore* sessionObjectStore;
191193
ObjectStore* objectStore;

src/lib/common/Configuration.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ const struct config Configuration::valid_config[] = {
5151
{ "slots.removable", CONFIG_TYPE_BOOL },
5252
{ "slots.mechanisms", CONFIG_TYPE_STRING },
5353
{ "library.reset_on_fork", CONFIG_TYPE_BOOL },
54+
{ "objectstore.readrefresh", CONFIG_TYPE_BOOL },
5455
{ "", CONFIG_TYPE_UNSUPPORTED }
5556
};
5657

src/lib/common/softhsm2.conf.5.in

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,32 @@ library.reset_on_fork = true
102102
.fi
103103
.RE
104104
.LP
105+
.SH OBJECTSTORE.READREFRESH
106+
If set to false, then this will affect the refreshing of the object store in
107+
the following way before an object is used but not changed:
108+
.IP * 2
109+
No files will be read if 'objectstore.backend = file'.
110+
.IP * 2
111+
No wait for mutex to unlock if 'objectstore.backend = db'.
112+
.LP
113+
Depending of what kind of HW that is used setting 'false' may improve the
114+
performance of the HSM.
115+
.LP
116+
But the drawback is that if one processes is using an object handle from a
117+
token for multiple function calls then this process may still use the old
118+
unmodified or deleted object even if it is changed or deleted. Another
119+
process may have called C_DestroyObject or C_SetAttributeValue. But every
120+
time a process gets a new handle for an object the objectstore of this
121+
process is updated for all objects even if this property is false.
122+
.LP
123+
Default is true.
124+
.LP
125+
.RS
126+
.nf
127+
objectstore.readrefresh = false
128+
.fi
129+
.RE
130+
.LP
105131
.SH ENVIRONMENT
106132
.TP
107133
SOFTHSM2_CONF

src/lib/common/softhsm2.conf.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ slots.mechanisms = ALL
1515

1616
# If the library should reset the state on fork
1717
library.reset_on_fork = false
18+
19+
# Set to false if there should be no update of a token objects each time it is used.
20+
objectstore.readrefresh = true

src/lib/object_store/DBObject.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,10 +1362,15 @@ bool DBObject::deleteAttribute(CK_ATTRIBUTE_TYPE type)
13621362
}
13631363

13641364
// The validity state of the object
1365-
bool DBObject::isValid()
1365+
// If not 'doRefresh' we know that the object allready exists in the DB
1366+
// and hence _objectId should have been initialized.
1367+
bool DBObject::isValid(const bool doRefresh)
13661368
{
1367-
MutexLocker lock(_mutex);
1368-
1369+
if (doRefresh)
1370+
{
1371+
// Wait for update of object.
1372+
MutexLocker lock(_mutex);
1373+
}
13691374
return _objectId != 0 && _connection != NULL;
13701375
}
13711376

src/lib/object_store/DBObject.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class DBObject : public OSObject
9696
virtual bool deleteAttribute(CK_ATTRIBUTE_TYPE type);
9797

9898
// The validity state of the object
99-
virtual bool isValid();
99+
virtual bool isValid(bool doRefresh);
100100

101101
// Start an attribute set transaction; this method is used when - for
102102
// example - a key is generated and all its attributes need to be

src/lib/object_store/DBToken.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ OSObject *DBToken::createObject()
679679
return NULL;
680680
}
681681

682-
if (!newObject->isValid())
682+
if (!newObject->isValid(true))
683683
{
684684
newObject->abortTransaction();
685685
delete newObject;

src/lib/object_store/OSObject.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ class OSObject
6464
virtual bool deleteAttribute(CK_ATTRIBUTE_TYPE type) = 0;
6565

6666
// The validity state of the object
67-
virtual bool isValid() = 0;
67+
// If doRefresh==true then update the object from the storage before validating.
68+
virtual bool isValid(bool doRefresh=true) = 0;
6869

6970
// Start an attribute set transaction; this method is used when - for
7071
// example - a key is generated and all its attributes need to be

src/lib/object_store/ObjectFile.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,13 @@ bool ObjectFile::deleteAttribute(CK_ATTRIBUTE_TYPE type)
262262
return valid;
263263
}
264264

265-
// The validity state of the object (refresh from disk as a side effect)
266-
bool ObjectFile::isValid()
265+
// The validity state of the object (may refresh from disk as a side effect)
266+
bool ObjectFile::isValid(const bool doRefresh)
267267
{
268-
refresh();
269-
268+
if(doRefresh)
269+
{
270+
refresh();
271+
}
270272
return valid;
271273
}
272274

src/lib/object_store/ObjectFile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class ObjectFile : public OSObject
7676
virtual bool deleteAttribute(CK_ATTRIBUTE_TYPE type);
7777

7878
// The validity state of the object (refresh from disk as a side effect)
79-
virtual bool isValid();
79+
virtual bool isValid(bool doRefresh=true);
8080

8181
// Invalidate the object file externally; this method is normally
8282
// only called by the OSToken class in case an object file has

src/lib/object_store/SessionObject.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ bool SessionObject::deleteAttribute(CK_ATTRIBUTE_TYPE type)
217217
}
218218

219219
// The validity state of the object
220-
bool SessionObject::isValid()
220+
// the doRefresh parameter has no meaning for this implementation since noting is stored on disk.
221+
bool SessionObject::isValid(const bool doRefresh __attribute__((unused)))
221222
{
222223
return valid;
223224
}

src/lib/object_store/SessionObject.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class SessionObject : public OSObject
7373
virtual bool deleteAttribute(CK_ATTRIBUTE_TYPE type);
7474

7575
// The validity state of the object
76-
virtual bool isValid();
76+
virtual bool isValid(bool doRefresh);
7777

7878
bool hasSlotID(CK_SLOT_ID inSlotID);
7979

src/lib/object_store/SessionObjectStore.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ SessionObject* SessionObjectStore::createObject(CK_SLOT_ID slotID, CK_SESSION_HA
106106
// Create the new object file
107107
SessionObject* newObject = new SessionObject(this, slotID, hSession, isPrivate);
108108

109-
if (!newObject->isValid())
109+
if (!newObject->isValid(false))
110110
{
111111
ERROR_MSG("Failed to create new object");
112112

0 commit comments

Comments
 (0)