1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
--- lib/softoken/sftkdb.c.orig 2010-06-24 13:58:26.000000000 +0200
+++ lib/softoken/sftkdb.c 2010-06-24 13:58:37.000000000 +0200
@@ -509,18 +509,23 @@
CK_ULONG count)
{
int i;
+ CK_RV crv;
SFTKDBHandle *keyHandle = handle;
SDB *keyTarget = NULL;
+ PRBool usingPeerDB = PR_FALSE;
+ PRBool inPeerDBTransaction = PR_FALSE;
PORT_Assert(handle);
if (handle->type != SFTK_KEYDB_TYPE) {
keyHandle = handle->peerDB;
+ usingPeerDB = PR_TRUE;
}
/* no key DB defined? then no need to sign anything */
if (keyHandle == NULL) {
- return CKR_OK;
+ crv = CKR_OK;
+ goto loser;
}
/* When we are in a middle of an update, we have an update database set,
@@ -532,7 +537,17 @@
/* skip the the database does not support meta data */
if ((keyTarget->sdb_flags & SDB_HAS_META) == 0) {
- return CKR_OK;
+ crv = CKR_OK;
+ goto loser;
+ }
+
+ /* If we had to switch databases, we need to initialize a transaction. */
+ if (usingPeerDB) {
+ crv = (*keyTarget->sdb_Begin)(keyTarget);
+ if (crv != CKR_OK) {
+ goto loser;
+ }
+ inPeerDBTransaction = PR_TRUE;
}
for (i=0; i < count; i ++) {
@@ -546,23 +561,44 @@
PZ_Lock(keyHandle->passwordLock);
if (keyHandle->passwordKey.data == NULL) {
PZ_Unlock(keyHandle->passwordLock);
- return CKR_USER_NOT_LOGGED_IN;
+ crv = CKR_USER_NOT_LOGGED_IN;
+ goto loser;
}
rv = sftkdb_SignAttribute(arena, &keyHandle->passwordKey,
objectID, template[i].type,
&plainText, &signText);
PZ_Unlock(keyHandle->passwordLock);
if (rv != SECSuccess) {
- return CKR_GENERAL_ERROR; /* better error code here? */
+ crv = CKR_GENERAL_ERROR; /* better error code here? */
+ goto loser;
}
rv = sftkdb_PutAttributeSignature(handle, keyTarget,
objectID, template[i].type, signText);
if (rv != SECSuccess) {
- return CKR_GENERAL_ERROR; /* better error code here? */
+ crv = CKR_GENERAL_ERROR; /* better error code here? */
+ goto loser;
}
}
}
- return CKR_OK;
+ crv = CKR_OK;
+
+ /* If necessary, commit the transaction */
+ if (inPeerDBTransaction) {
+ crv = (*keyTarget->sdb_Commit)(keyTarget);
+ if (crv != CKR_OK) {
+ goto loser;
+ }
+ inPeerDBTransaction = PR_FALSE;
+ }
+
+loser:
+ if (inPeerDBTransaction) {
+ /* The transaction must have failed. Abort. */
+ (*keyTarget->sdb_Abort)(keyTarget);
+ PORT_Assert(crv != CKR_OK);
+ if (crv == CKR_OK) crv = CKR_GENERAL_ERROR;
+ }
+ return crv;
}
static CK_RV
@@ -766,6 +802,11 @@
if (attr == NULL) {
return CKR_TEMPLATE_INCOMPLETE;
}
+ if (attr->ulValueLen == 0) {
+ /* key is to generic to determine that it's unique, usually
+ * happens in the key gen case */
+ return CKR_OBJECT_HANDLE_INVALID;
+ }
findTemplate[1] = *attr;
count = 2;
break;
@@ -827,6 +868,11 @@
}
crv = sftkdb_getFindTemplate(objectType, objTypeData,
findTemplate, &count, ptemplate, len);
+ if (crv == CKR_OBJECT_HANDLE_INVALID) {
+ /* key is to generic to determine that it's unique, usually
+ * happens in the key gen case, go ahead and just create it */
+ return CKR_OK;
+ }
if (crv != CKR_OK) {
return crv;
}
|