Skip to content

Commit 41818bc

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 3de5981 commit 41818bc

File tree

14 files changed

+79
-36
lines changed

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);
@@ -2410,7 +2412,7 @@ CK_RV SoftHSM::AsymEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMec
24102412

24112413
// Check the key handle.
24122414
OSObject *key = (OSObject *)handleManager->getObject(hKey);
2413-
if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
2415+
if (key == NULL_PTR || !key->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
24142416

24152417
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
24162418
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -2882,7 +2884,7 @@ CK_RV SoftHSM::SymDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
28822884

28832885
// Check the key handle.
28842886
OSObject *key = (OSObject *)handleManager->getObject(hKey);
2885-
if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
2887+
if (key == NULL_PTR || !key->isValid(doRefresh)) return CKR_OBJECT_HANDLE_INVALID;
28862888

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

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

31353137
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
31363138
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -3773,7 +3775,7 @@ CK_RV SoftHSM::C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
37733775

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

37783780
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
37793781
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -3924,7 +3926,7 @@ CK_RV SoftHSM::MacSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechani
39243926

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

39293931
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
39303932
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -4076,7 +4078,7 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
40764078

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

40814083
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
40824084
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -4902,7 +4904,7 @@ CK_RV SoftHSM::MacVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMecha
49024904

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

49074909
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
49084910
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -5054,7 +5056,7 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
50545056

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

50595061
CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
50605062
CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -6490,7 +6492,7 @@ CK_RV SoftHSM::C_WrapKey
64906492

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

64956497
CK_BBOOL isWrapKeyOnToken = wrapKey->getBooleanValue(CKA_TOKEN, false);
64966498
CK_BBOOL isWrapKeyPrivate = wrapKey->getBooleanValue(CKA_PRIVATE, true);
@@ -6532,7 +6534,7 @@ CK_RV SoftHSM::C_WrapKey
65326534

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

65376539
CK_BBOOL isKeyOnToken = key->getBooleanValue(CKA_TOKEN, false);
65386540
CK_BBOOL isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -6957,7 +6959,7 @@ CK_RV SoftHSM::C_UnwrapKey
69576959

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

69626964
CK_BBOOL isUnwrapKeyOnToken = unwrapKey->getBooleanValue(CKA_TOKEN, false);
69636965
CK_BBOOL isUnwrapKeyPrivate = unwrapKey->getBooleanValue(CKA_PRIVATE, true);
@@ -7255,7 +7257,7 @@ CK_RV SoftHSM::C_DeriveKey
72557257

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

72607262
CK_BBOOL isKeyOnToken = key->getBooleanValue(CKA_TOKEN, false);
72617263
CK_BBOOL isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, true);
@@ -10358,7 +10360,7 @@ CK_RV SoftHSM::deriveDH
1035810360

1035910361
// Get the base key handle
1036010362
OSObject *baseKey = (OSObject *)handleManager->getObject(hBaseKey);
10361-
if (baseKey == NULL || !baseKey->isValid())
10363+
if (baseKey == NULL || !baseKey->isValid(doRefresh))
1036210364
return CKR_KEY_HANDLE_INVALID;
1036310365

1036410366
// Get the DH algorithm handler
@@ -10690,7 +10692,7 @@ CK_RV SoftHSM::deriveECDH
1069010692

1069110693
// Get the base key handle
1069210694
OSObject *baseKey = (OSObject *)handleManager->getObject(hBaseKey);
10693-
if (baseKey == NULL || !baseKey->isValid())
10695+
if (baseKey == NULL || !baseKey->isValid(doRefresh))
1069410696
return CKR_KEY_HANDLE_INVALID;
1069510697

1069610698
// Get the ECDH algorithm handler
@@ -11044,7 +11046,7 @@ CK_RV SoftHSM::deriveEDDSA
1104411046

1104511047
// Get the base key handle
1104611048
OSObject *baseKey = (OSObject *)handleManager->getObject(hBaseKey);
11047-
if (baseKey == NULL || !baseKey->isValid())
11049+
if (baseKey == NULL || !baseKey->isValid(doRefresh))
1104811050
return CKR_KEY_HANDLE_INVALID;
1104911051

1105011052
// Get the EDDSA algorithm handler
@@ -11570,7 +11572,7 @@ CK_RV SoftHSM::deriveSymmetric
1157011572

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

1157511577
// Get the data
1157611578
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

0 commit comments

Comments
 (0)