OLD | NEW |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 /* | 4 /* |
5 * This file manages object type indepentent functions. | 5 * This file manages object type indepentent functions. |
6 */ | 6 */ |
7 #include "seccomon.h" | 7 #include "seccomon.h" |
8 #include "secmod.h" | 8 #include "secmod.h" |
9 #include "secmodi.h" | 9 #include "secmodi.h" |
10 #include "secmodti.h" | 10 #include "secmodti.h" |
11 #include "pkcs11.h" | 11 #include "pkcs11.h" |
12 #include "pkcs11t.h" | 12 #include "pkcs11t.h" |
13 #include "pk11func.h" | 13 #include "pk11func.h" |
14 #include "key.h" | 14 #include "key.h" |
15 #include "secitem.h" | 15 #include "secitem.h" |
16 #include "secerr.h" | 16 #include "secerr.h" |
17 #include "sslerr.h" | 17 #include "sslerr.h" |
18 | 18 |
19 #define PK11_SEARCH_CHUNKSIZE 10 | 19 #define PK11_SEARCH_CHUNKSIZE 10 |
20 | 20 |
21 /* | 21 /* |
22 * Build a block big enough to hold the data | 22 * Build a block big enough to hold the data |
23 */ | 23 */ |
24 SECItem * | 24 SECItem *PK11_BlockData(SECItem *data, unsigned long size) { |
25 PK11_BlockData(SECItem *data,unsigned long size) { | 25 SECItem *newData; |
26 SECItem *newData; | 26 |
27 | 27 newData = (SECItem *)PORT_Alloc(sizeof(SECItem)); |
28 newData = (SECItem *)PORT_Alloc(sizeof(SECItem)); | 28 if (newData == NULL) return NULL; |
29 if (newData == NULL) return NULL; | 29 |
30 | 30 newData->len = (data->len + (size - 1)) / size; |
31 newData->len = (data->len + (size-1))/size; | 31 newData->len *= size; |
32 newData->len *= size; | 32 |
33 | 33 newData->data = (unsigned char *)PORT_ZAlloc(newData->len); |
34 newData->data = (unsigned char *) PORT_ZAlloc(newData->len);· | 34 if (newData->data == NULL) { |
35 if (newData->data == NULL) { | 35 PORT_Free(newData); |
36 » PORT_Free(newData); | 36 return NULL; |
37 » return NULL; | 37 } |
38 } | 38 PORT_Memset(newData->data, newData->len - data->len, newData->len); |
39 PORT_Memset(newData->data,newData->len-data->len,newData->len);· | 39 PORT_Memcpy(newData->data, data->data, data->len); |
40 PORT_Memcpy(newData->data,data->data,data->len); | 40 return newData; |
41 return newData; | 41 } |
42 } | 42 |
43 | 43 SECStatus PK11_DestroyObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE object) { |
44 | 44 CK_RV crv; |
45 SECStatus | 45 |
46 PK11_DestroyObject(PK11SlotInfo *slot,CK_OBJECT_HANDLE object) { | 46 PK11_EnterSlotMonitor(slot); |
47 CK_RV crv; | 47 crv = PK11_GETTAB(slot)->C_DestroyObject(slot->session, object); |
48 | 48 PK11_ExitSlotMonitor(slot); |
49 PK11_EnterSlotMonitor(slot); | 49 if (crv != CKR_OK) { |
50 crv = PK11_GETTAB(slot)->C_DestroyObject(slot->session,object); | 50 return SECFailure; |
51 PK11_ExitSlotMonitor(slot); | 51 } |
52 if (crv != CKR_OK) { | 52 return SECSuccess; |
53 » return SECFailure; | 53 } |
54 } | 54 |
55 return SECSuccess; | 55 SECStatus PK11_DestroyTokenObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE object) { |
56 } | 56 CK_RV crv; |
57 | 57 SECStatus rv = SECSuccess; |
58 SECStatus | 58 CK_SESSION_HANDLE rwsession; |
59 PK11_DestroyTokenObject(PK11SlotInfo *slot,CK_OBJECT_HANDLE object) { | 59 |
60 CK_RV crv; | 60 rwsession = PK11_GetRWSession(slot); |
61 SECStatus rv = SECSuccess; | 61 if (rwsession == CK_INVALID_SESSION) { |
62 CK_SESSION_HANDLE rwsession; | 62 PORT_SetError(SEC_ERROR_BAD_DATA); |
63 | 63 return SECFailure; |
64 ·· | 64 } |
65 rwsession = PK11_GetRWSession(slot); | 65 |
66 if (rwsession == CK_INVALID_SESSION) { | 66 crv = PK11_GETTAB(slot)->C_DestroyObject(rwsession, object); |
67 » PORT_SetError(SEC_ERROR_BAD_DATA); | 67 if (crv != CKR_OK) { |
68 » return SECFailure; | 68 rv = SECFailure; |
69 } | 69 PORT_SetError(PK11_MapError(crv)); |
70 | 70 } |
71 crv = PK11_GETTAB(slot)->C_DestroyObject(rwsession,object); | 71 PK11_RestoreROSession(slot, rwsession); |
72 if (crv != CKR_OK) { | 72 return rv; |
73 » rv = SECFailure; | 73 } |
74 » PORT_SetError(PK11_MapError(crv)); | 74 |
75 } | 75 /* |
76 PK11_RestoreROSession(slot,rwsession); | 76 * Read in a single attribute into a SECItem. Allocate space for it with |
77 return rv; | |
78 } | |
79 | |
80 /* | |
81 * Read in a single attribute into a SECItem. Allocate space for it with· | |
82 * PORT_Alloc unless an arena is supplied. In the latter case use the arena | 77 * PORT_Alloc unless an arena is supplied. In the latter case use the arena |
83 * to allocate the space. | 78 * to allocate the space. |
84 * | 79 * |
85 * PK11_ReadAttribute sets the 'data' and 'len' fields of the SECItem but | 80 * PK11_ReadAttribute sets the 'data' and 'len' fields of the SECItem but |
86 * does not modify its 'type' field. | 81 * does not modify its 'type' field. |
87 */ | 82 */ |
88 SECStatus | 83 SECStatus PK11_ReadAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, |
89 PK11_ReadAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, | 84 CK_ATTRIBUTE_TYPE type, PLArenaPool *arena, |
90 » CK_ATTRIBUTE_TYPE type, PLArenaPool *arena, SECItem *result) { | 85 SECItem *result) { |
91 CK_ATTRIBUTE attr = { 0, NULL, 0 }; | 86 CK_ATTRIBUTE attr = {0, NULL, 0}; |
92 CK_RV crv; | 87 CK_RV crv; |
93 | 88 |
94 attr.type = type; | 89 attr.type = type; |
95 | 90 |
96 PK11_EnterSlotMonitor(slot); | 91 PK11_EnterSlotMonitor(slot); |
97 crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,id,&attr,1); | 92 crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session, id, &attr, 1); |
98 if (crv != CKR_OK) { | 93 if (crv != CKR_OK) { |
99 » PK11_ExitSlotMonitor(slot); | |
100 » PORT_SetError(PK11_MapError(crv)); | |
101 » return SECFailure; | |
102 } | |
103 if (arena) { | |
104 » attr.pValue = PORT_ArenaAlloc(arena,attr.ulValueLen); | |
105 } else { | |
106 » attr.pValue = PORT_Alloc(attr.ulValueLen); | |
107 } | |
108 if (attr.pValue == NULL) { | |
109 » PK11_ExitSlotMonitor(slot); | |
110 » return SECFailure; | |
111 } | |
112 crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,id,&attr,1); | |
113 PK11_ExitSlotMonitor(slot); | 94 PK11_ExitSlotMonitor(slot); |
114 if (crv != CKR_OK) { | 95 PORT_SetError(PK11_MapError(crv)); |
115 » PORT_SetError(PK11_MapError(crv)); | 96 return SECFailure; |
116 » if (!arena) PORT_Free(attr.pValue); | 97 } |
117 » return SECFailure; | 98 if (arena) { |
118 } | 99 attr.pValue = PORT_ArenaAlloc(arena, attr.ulValueLen); |
119 | 100 } else { |
120 result->data = (unsigned char*)attr.pValue; | 101 attr.pValue = PORT_Alloc(attr.ulValueLen); |
121 result->len = attr.ulValueLen; | 102 } |
122 | 103 if (attr.pValue == NULL) { |
123 return SECSuccess; | 104 PK11_ExitSlotMonitor(slot); |
124 } | 105 return SECFailure; |
125 | 106 } |
126 /* | 107 crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session, id, &attr, 1); |
127 * Read in a single attribute into As a Ulong.· | 108 PK11_ExitSlotMonitor(slot); |
| 109 if (crv != CKR_OK) { |
| 110 PORT_SetError(PK11_MapError(crv)); |
| 111 if (!arena) PORT_Free(attr.pValue); |
| 112 return SECFailure; |
| 113 } |
| 114 |
| 115 result->data = (unsigned char *)attr.pValue; |
| 116 result->len = attr.ulValueLen; |
| 117 |
| 118 return SECSuccess; |
| 119 } |
| 120 |
| 121 /* |
| 122 * Read in a single attribute into As a Ulong. |
128 */ | 123 */ |
129 CK_ULONG | 124 CK_ULONG |
130 PK11_ReadULongAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, | 125 PK11_ReadULongAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, |
131 » CK_ATTRIBUTE_TYPE type) { | 126 CK_ATTRIBUTE_TYPE type) { |
132 CK_ATTRIBUTE attr; | 127 CK_ATTRIBUTE attr; |
133 CK_ULONG value = CK_UNAVAILABLE_INFORMATION; | 128 CK_ULONG value = CK_UNAVAILABLE_INFORMATION; |
134 CK_RV crv; | 129 CK_RV crv; |
135 | 130 |
136 PK11_SETATTRS(&attr,type,&value,sizeof(value)); | 131 PK11_SETATTRS(&attr, type, &value, sizeof(value)); |
137 | 132 |
138 PK11_EnterSlotMonitor(slot); | 133 PK11_EnterSlotMonitor(slot); |
139 crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,id,&attr,1); | 134 crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session, id, &attr, 1); |
140 PK11_ExitSlotMonitor(slot); | 135 PK11_ExitSlotMonitor(slot); |
141 if (crv != CKR_OK) { | 136 if (crv != CKR_OK) { |
142 » PORT_SetError(PK11_MapError(crv)); | 137 PORT_SetError(PK11_MapError(crv)); |
143 } | 138 } |
144 return value; | 139 return value; |
145 } | 140 } |
146 | 141 |
147 /* | 142 /* |
148 * check to see if a bool has been set. | 143 * check to see if a bool has been set. |
149 */ | 144 */ |
150 CK_BBOOL | 145 CK_BBOOL |
151 PK11_HasAttributeSet( PK11SlotInfo *slot, CK_OBJECT_HANDLE id, | 146 PK11_HasAttributeSet(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, |
152 » » » » CK_ATTRIBUTE_TYPE type, PRBool haslock ) | 147 CK_ATTRIBUTE_TYPE type, PRBool haslock) { |
153 { | 148 CK_BBOOL ckvalue = CK_FALSE; |
154 CK_BBOOL ckvalue = CK_FALSE; | 149 CK_ATTRIBUTE theTemplate; |
155 CK_ATTRIBUTE theTemplate; | 150 CK_RV crv; |
156 CK_RV crv; | 151 |
157 | 152 /* Prepare to retrieve the attribute. */ |
158 /* Prepare to retrieve the attribute. */ | 153 PK11_SETATTRS(&theTemplate, type, &ckvalue, sizeof(CK_BBOOL)); |
159 PK11_SETATTRS( &theTemplate, type, &ckvalue, sizeof( CK_BBOOL ) ); | 154 |
160 | 155 /* Retrieve attribute value. */ |
161 /* Retrieve attribute value. */ | 156 if (!haslock) PK11_EnterSlotMonitor(slot); |
162 if (!haslock) PK11_EnterSlotMonitor(slot); | 157 crv = PK11_GETTAB(slot) |
163 crv = PK11_GETTAB( slot )->C_GetAttributeValue( slot->session, id, | 158 ->C_GetAttributeValue(slot->session, id, &theTemplate, 1); |
164 &theTemplate, 1 ); | 159 if (!haslock) PK11_ExitSlotMonitor(slot); |
165 if (!haslock) PK11_ExitSlotMonitor(slot); | 160 if (crv != CKR_OK) { |
166 if( crv != CKR_OK ) { | 161 PORT_SetError(PK11_MapError(crv)); |
167 PORT_SetError( PK11_MapError( crv ) ); | 162 return CK_FALSE; |
168 return CK_FALSE; | 163 } |
169 } | 164 |
170 | 165 return ckvalue; |
171 return ckvalue; | |
172 } | 166 } |
173 | 167 |
174 /* | 168 /* |
175 * returns a full list of attributes. Allocate space for them. If an arena is | 169 * returns a full list of attributes. Allocate space for them. If an arena is |
176 * provided, allocate space out of the arena. | 170 * provided, allocate space out of the arena. |
177 */ | 171 */ |
178 CK_RV | 172 CK_RV |
179 PK11_GetAttributes(PLArenaPool *arena,PK11SlotInfo *slot, | 173 PK11_GetAttributes(PLArenaPool *arena, PK11SlotInfo *slot, CK_OBJECT_HANDLE obj, |
180 » » » CK_OBJECT_HANDLE obj,CK_ATTRIBUTE *attr, int count) | 174 CK_ATTRIBUTE *attr, int count) { |
181 { | 175 int i; |
182 int i; | 176 /* make pedantic happy... note that it's only used arena != NULL */ |
183 /* make pedantic happy... note that it's only used arena != NULL */· | 177 void *mark = NULL; |
184 void *mark = NULL;· | 178 CK_RV crv; |
185 CK_RV crv; | 179 PORT_Assert(slot->session != CK_INVALID_SESSION); |
186 PORT_Assert(slot->session != CK_INVALID_SESSION); | 180 if (slot->session == CK_INVALID_SESSION) return CKR_SESSION_HANDLE_INVALID; |
187 if (slot->session == CK_INVALID_SESSION) | 181 |
188 » return CKR_SESSION_HANDLE_INVALID; | 182 /* |
189 | 183 * first get all the lengths of the parameters. |
190 /* | 184 */ |
191 * first get all the lengths of the parameters. | 185 PK11_EnterSlotMonitor(slot); |
192 */ | 186 crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session, obj, attr, count); |
193 PK11_EnterSlotMonitor(slot); | 187 if (crv != CKR_OK) { |
194 crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,obj,attr,count); | 188 PK11_ExitSlotMonitor(slot); |
195 if (crv != CKR_OK) { | 189 return crv; |
196 » PK11_ExitSlotMonitor(slot); | 190 } |
197 » return crv; | 191 |
| 192 if (arena) { |
| 193 mark = PORT_ArenaMark(arena); |
| 194 if (mark == NULL) return CKR_HOST_MEMORY; |
| 195 } |
| 196 |
| 197 /* |
| 198 * now allocate space to store the results. |
| 199 */ |
| 200 for (i = 0; i < count; i++) { |
| 201 if (attr[i].ulValueLen == 0) continue; |
| 202 if (arena) { |
| 203 attr[i].pValue = PORT_ArenaAlloc(arena, attr[i].ulValueLen); |
| 204 if (attr[i].pValue == NULL) { |
| 205 /* arena failures, just release the mark */ |
| 206 PORT_ArenaRelease(arena, mark); |
| 207 PK11_ExitSlotMonitor(slot); |
| 208 return CKR_HOST_MEMORY; |
| 209 } |
| 210 } else { |
| 211 attr[i].pValue = PORT_Alloc(attr[i].ulValueLen); |
| 212 if (attr[i].pValue == NULL) { |
| 213 /* Separate malloc failures, loop to release what we have |
| 214 * so far */ |
| 215 int j; |
| 216 for (j = 0; j < i; j++) { |
| 217 PORT_Free(attr[j].pValue); |
| 218 /* don't give the caller pointers to freed memory */ |
| 219 attr[j].pValue = NULL; |
| 220 } |
| 221 PK11_ExitSlotMonitor(slot); |
| 222 return CKR_HOST_MEMORY; |
| 223 } |
198 } | 224 } |
199 | 225 } |
| 226 |
| 227 /* |
| 228 * finally get the results. |
| 229 */ |
| 230 crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session, obj, attr, count); |
| 231 PK11_ExitSlotMonitor(slot); |
| 232 if (crv != CKR_OK) { |
200 if (arena) { | 233 if (arena) { |
201 » mark = PORT_ArenaMark(arena); | 234 PORT_ArenaRelease(arena, mark); |
202 » if (mark == NULL) return CKR_HOST_MEMORY; | 235 } else { |
| 236 for (i = 0; i < count; i++) { |
| 237 PORT_Free(attr[i].pValue); |
| 238 /* don't give the caller pointers to freed memory */ |
| 239 attr[i].pValue = NULL; |
| 240 } |
203 } | 241 } |
204 | 242 } else if (arena && mark) { |
205 /* | 243 PORT_ArenaUnmark(arena, mark); |
206 * now allocate space to store the results. | 244 } |
207 */ | 245 return crv; |
208 for (i=0; i < count; i++) { | 246 } |
209 » if (attr[i].ulValueLen == 0) | 247 |
210 » continue; | 248 PRBool PK11_IsPermObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle) { |
211 » if (arena) { | 249 return (PRBool)PK11_HasAttributeSet(slot, handle, CKA_TOKEN, PR_FALSE); |
212 » attr[i].pValue = PORT_ArenaAlloc(arena,attr[i].ulValueLen); | 250 } |
213 » if (attr[i].pValue == NULL) { | 251 |
214 » » /* arena failures, just release the mark */ | 252 char *PK11_GetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id) { |
215 » » PORT_ArenaRelease(arena,mark); | 253 char *nickname = NULL; |
216 » » PK11_ExitSlotMonitor(slot); | 254 SECItem result; |
217 » » return CKR_HOST_MEMORY; | 255 SECStatus rv; |
218 » } | 256 |
219 » } else { | 257 rv = PK11_ReadAttribute(slot, id, CKA_LABEL, NULL, &result); |
220 » attr[i].pValue = PORT_Alloc(attr[i].ulValueLen); | 258 if (rv != SECSuccess) { |
221 » if (attr[i].pValue == NULL) { | 259 return NULL; |
222 » » /* Separate malloc failures, loop to release what we have· | 260 } |
223 » » * so far */ | 261 |
224 » » int j; | 262 nickname = PORT_ZAlloc(result.len + 1); |
225 » » for (j= 0; j < i; j++) {· | 263 if (nickname == NULL) { |
226 » » PORT_Free(attr[j].pValue); | |
227 » » /* don't give the caller pointers to freed memory */ | |
228 » » attr[j].pValue = NULL;· | |
229 » » } | |
230 » » PK11_ExitSlotMonitor(slot); | |
231 » » return CKR_HOST_MEMORY; | |
232 » } | |
233 » } | |
234 } | |
235 | |
236 /* | |
237 * finally get the results. | |
238 */ | |
239 crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,obj,attr,count); | |
240 PK11_ExitSlotMonitor(slot); | |
241 if (crv != CKR_OK) { | |
242 » if (arena) { | |
243 » PORT_ArenaRelease(arena,mark); | |
244 » } else { | |
245 » for (i= 0; i < count; i++) { | |
246 » » PORT_Free(attr[i].pValue); | |
247 » » /* don't give the caller pointers to freed memory */ | |
248 » » attr[i].pValue = NULL; | |
249 » } | |
250 » } | |
251 } else if (arena && mark) { | |
252 » PORT_ArenaUnmark(arena,mark); | |
253 } | |
254 return crv; | |
255 } | |
256 | |
257 PRBool | |
258 PK11_IsPermObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle) | |
259 { | |
260 return (PRBool) PK11_HasAttributeSet(slot, handle, CKA_TOKEN, PR_FALSE); | |
261 } | |
262 | |
263 char * | |
264 PK11_GetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id)· | |
265 { | |
266 char *nickname = NULL; | |
267 SECItem result; | |
268 SECStatus rv; | |
269 | |
270 rv = PK11_ReadAttribute(slot,id,CKA_LABEL,NULL,&result); | |
271 if (rv != SECSuccess) { | |
272 » return NULL; | |
273 } | |
274 | |
275 nickname = PORT_ZAlloc(result.len+1); | |
276 if (nickname == NULL) { | |
277 » PORT_Free(result.data); | |
278 » return NULL; | |
279 } | |
280 PORT_Memcpy(nickname, result.data, result.len); | |
281 PORT_Free(result.data); | 264 PORT_Free(result.data); |
282 return nickname; | 265 return NULL; |
283 } | 266 } |
284 | 267 PORT_Memcpy(nickname, result.data, result.len); |
285 SECStatus | 268 PORT_Free(result.data); |
286 PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,· | 269 return nickname; |
287 » » » » » » const char *nickname) | 270 } |
288 { | 271 |
289 int len = PORT_Strlen(nickname); | 272 SECStatus PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, |
290 CK_ATTRIBUTE setTemplate; | 273 const char *nickname) { |
291 CK_RV crv; | 274 int len = PORT_Strlen(nickname); |
292 CK_SESSION_HANDLE rwsession; | 275 CK_ATTRIBUTE setTemplate; |
293 | 276 CK_RV crv; |
294 if (len < 0) { | 277 CK_SESSION_HANDLE rwsession; |
295 » return SECFailure; | 278 |
296 } | 279 if (len < 0) { |
297 | 280 return SECFailure; |
298 PK11_SETATTRS(&setTemplate, CKA_LABEL, (CK_CHAR *) nickname, len); | 281 } |
299 rwsession = PK11_GetRWSession(slot); | 282 |
300 if (rwsession == CK_INVALID_SESSION) { | 283 PK11_SETATTRS(&setTemplate, CKA_LABEL, (CK_CHAR *)nickname, len); |
301 » PORT_SetError(SEC_ERROR_BAD_DATA); | 284 rwsession = PK11_GetRWSession(slot); |
302 » return SECFailure; | 285 if (rwsession == CK_INVALID_SESSION) { |
303 } | 286 PORT_SetError(SEC_ERROR_BAD_DATA); |
304 crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession, id, | 287 return SECFailure; |
305 » » » &setTemplate, 1); | 288 } |
306 PK11_RestoreROSession(slot, rwsession); | 289 crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession, id, &setTemplate, 1); |
307 if (crv != CKR_OK) { | 290 PK11_RestoreROSession(slot, rwsession); |
308 » PORT_SetError(PK11_MapError(crv)); | 291 if (crv != CKR_OK) { |
309 » return SECFailure; | 292 PORT_SetError(PK11_MapError(crv)); |
310 } | 293 return SECFailure; |
311 return SECSuccess; | 294 } |
| 295 return SECSuccess; |
312 } | 296 } |
313 | 297 |
314 /* | 298 /* |
315 * strip leading zero's from key material | 299 * strip leading zero's from key material |
316 */ | 300 */ |
317 void | 301 void pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib) { |
318 pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib) { | 302 char *ptr = (char *)attrib->pValue; |
319 char *ptr = (char *)attrib->pValue; | 303 unsigned long len = attrib->ulValueLen; |
320 unsigned long len = attrib->ulValueLen; | 304 |
321 | 305 while ((len > 1) && (*ptr == 0)) { |
322 while ((len > 1) && (*ptr == 0)) { | 306 len--; |
323 » len--; | 307 ptr++; |
324 » ptr++; | 308 } |
325 } | 309 attrib->pValue = ptr; |
326 attrib->pValue = ptr; | 310 attrib->ulValueLen = len; |
327 attrib->ulValueLen = len; | |
328 } | 311 } |
329 | 312 |
330 /* | 313 /* |
331 * get a new session on a slot. If we run out of session, use the slot's | 314 * get a new session on a slot. If we run out of session, use the slot's |
332 * 'exclusive' session. In this case owner becomes false. | 315 * 'exclusive' session. In this case owner becomes false. |
333 */ | 316 */ |
334 CK_SESSION_HANDLE | 317 CK_SESSION_HANDLE |
335 pk11_GetNewSession(PK11SlotInfo *slot,PRBool *owner) | 318 pk11_GetNewSession(PK11SlotInfo *slot, PRBool *owner) { |
336 { | 319 CK_SESSION_HANDLE session; |
337 CK_SESSION_HANDLE session; | 320 *owner = PR_TRUE; |
338 *owner = PR_TRUE; | 321 if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); |
339 if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); | 322 if (PK11_GETTAB(slot)->C_OpenSession(slot->slotID, CKF_SERIAL_SESSION, slot, |
340 if ( PK11_GETTAB(slot)->C_OpenSession(slot->slotID,CKF_SERIAL_SESSION,· | 323 pk11_notify, &session) != CKR_OK) { |
341 » » » slot,pk11_notify,&session) != CKR_OK) { | 324 *owner = PR_FALSE; |
342 » *owner = PR_FALSE; | 325 session = slot->session; |
343 » session = slot->session; | 326 } |
| 327 if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); |
| 328 |
| 329 return session; |
| 330 } |
| 331 |
| 332 void pk11_CloseSession(PK11SlotInfo *slot, CK_SESSION_HANDLE session, |
| 333 PRBool owner) { |
| 334 if (!owner) return; |
| 335 if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); |
| 336 (void)PK11_GETTAB(slot)->C_CloseSession(session); |
| 337 if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); |
| 338 } |
| 339 |
| 340 SECStatus PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session, |
| 341 const CK_ATTRIBUTE *theTemplate, int count, |
| 342 PRBool token, CK_OBJECT_HANDLE *objectID) { |
| 343 CK_SESSION_HANDLE rwsession; |
| 344 CK_RV crv; |
| 345 SECStatus rv = SECSuccess; |
| 346 |
| 347 rwsession = session; |
| 348 if (token) { |
| 349 rwsession = PK11_GetRWSession(slot); |
| 350 } else if (rwsession == CK_INVALID_SESSION) { |
| 351 rwsession = slot->session; |
| 352 if (rwsession != CK_INVALID_SESSION) PK11_EnterSlotMonitor(slot); |
| 353 } |
| 354 if (rwsession == CK_INVALID_SESSION) { |
| 355 PORT_SetError(SEC_ERROR_BAD_DATA); |
| 356 return SECFailure; |
| 357 } |
| 358 crv = PK11_GETTAB(slot)->C_CreateObject( |
| 359 rwsession, |
| 360 /* cast away const :-( */(CK_ATTRIBUTE_PTR)theTemplate, count, objectID); |
| 361 if (crv != CKR_OK) { |
| 362 PORT_SetError(PK11_MapError(crv)); |
| 363 rv = SECFailure; |
| 364 } |
| 365 if (token) { |
| 366 PK11_RestoreROSession(slot, rwsession); |
| 367 } else if (session == CK_INVALID_SESSION) { |
| 368 PK11_ExitSlotMonitor(slot); |
| 369 } |
| 370 |
| 371 return rv; |
| 372 } |
| 373 |
| 374 /* This function may add a maximum of 9 attributes. */ |
| 375 unsigned int pk11_OpFlagsToAttributes(CK_FLAGS flags, CK_ATTRIBUTE *attrs, |
| 376 CK_BBOOL *ckTrue) { |
| 377 |
| 378 const static CK_ATTRIBUTE_TYPE attrTypes[12] = { |
| 379 CKA_ENCRYPT, CKA_DECRYPT, 0 /* DIGEST */, CKA_SIGN, |
| 380 CKA_SIGN_RECOVER, CKA_VERIFY, CKA_VERIFY_RECOVER, 0 /* GEN */, |
| 381 0 /* GEN PAIR */, CKA_WRAP, CKA_UNWRAP, CKA_DERIVE}; |
| 382 |
| 383 const CK_ATTRIBUTE_TYPE *pType = attrTypes; |
| 384 CK_ATTRIBUTE *attr = attrs; |
| 385 CK_FLAGS test = CKF_ENCRYPT; |
| 386 |
| 387 PR_ASSERT(!(flags & ~CKF_KEY_OPERATION_FLAGS)); |
| 388 flags &= CKF_KEY_OPERATION_FLAGS; |
| 389 |
| 390 for (; flags && test <= CKF_DERIVE; test <<= 1, ++pType) { |
| 391 if (test & flags) { |
| 392 flags ^= test; |
| 393 PR_ASSERT(*pType); |
| 394 PK11_SETATTRS(attr, *pType, ckTrue, sizeof *ckTrue); |
| 395 ++attr; |
344 } | 396 } |
345 if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); | 397 } |
346 | 398 return (attr - attrs); |
347 return session; | |
348 } | |
349 | |
350 void | |
351 pk11_CloseSession(PK11SlotInfo *slot,CK_SESSION_HANDLE session,PRBool owner) | |
352 { | |
353 if (!owner) return; | |
354 if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); | |
355 (void) PK11_GETTAB(slot)->C_CloseSession(session); | |
356 if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); | |
357 } | |
358 | |
359 | |
360 SECStatus | |
361 PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session, | |
362 » » » » const CK_ATTRIBUTE *theTemplate, int count,· | |
363 » » » » PRBool token, CK_OBJECT_HANDLE *objectID) | |
364 { | |
365 » CK_SESSION_HANDLE rwsession; | |
366 » CK_RV crv; | |
367 » SECStatus rv = SECSuccess; | |
368 | |
369 » rwsession = session; | |
370 » if (token) { | |
371 » rwsession = PK11_GetRWSession(slot); | |
372 » } else if (rwsession == CK_INVALID_SESSION) { | |
373 » rwsession = slot->session; | |
374 » if (rwsession != CK_INVALID_SESSION) | |
375 » » PK11_EnterSlotMonitor(slot); | |
376 » } | |
377 » if (rwsession == CK_INVALID_SESSION) { | |
378 » PORT_SetError(SEC_ERROR_BAD_DATA); | |
379 » return SECFailure; | |
380 » } | |
381 » crv = PK11_GETTAB(slot)->C_CreateObject(rwsession,· | |
382 » /* cast away const :-( */ (CK_ATTRIBUTE_PTR)theTemplate, | |
383 » » » » » » count, objectID); | |
384 » if(crv != CKR_OK) { | |
385 » PORT_SetError( PK11_MapError(crv) ); | |
386 » rv = SECFailure; | |
387 » } | |
388 » if (token) { | |
389 » PK11_RestoreROSession(slot, rwsession); | |
390 » } else if (session == CK_INVALID_SESSION) { | |
391 » PK11_ExitSlotMonitor(slot); | |
392 } | |
393 | |
394 » return rv; | |
395 } | |
396 | |
397 | |
398 /* This function may add a maximum of 9 attributes. */ | |
399 unsigned int | |
400 pk11_OpFlagsToAttributes(CK_FLAGS flags, CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue) | |
401 { | |
402 | |
403 const static CK_ATTRIBUTE_TYPE attrTypes[12] = { | |
404 » CKA_ENCRYPT, CKA_DECRYPT, 0 /* DIGEST */, CKA_SIGN, | |
405 » CKA_SIGN_RECOVER, CKA_VERIFY, CKA_VERIFY_RECOVER, 0 /* GEN */, | |
406 » 0 /* GEN PAIR */, CKA_WRAP, CKA_UNWRAP, CKA_DERIVE· | |
407 }; | |
408 | |
409 const CK_ATTRIBUTE_TYPE *pType» = attrTypes; | |
410 CK_ATTRIBUTE *attr» = attrs; | |
411 CK_FLAGS test» = CKF_ENCRYPT; | |
412 | |
413 | |
414 PR_ASSERT(!(flags & ~CKF_KEY_OPERATION_FLAGS)); | |
415 flags &= CKF_KEY_OPERATION_FLAGS; | |
416 | |
417 for (; flags && test <= CKF_DERIVE; test <<= 1, ++pType) { | |
418 » if (test & flags) { | |
419 » flags ^= test; | |
420 » PR_ASSERT(*pType); | |
421 » PK11_SETATTRS(attr, *pType, ckTrue, sizeof *ckTrue);· | |
422 » ++attr; | |
423 » } | |
424 } | |
425 return (attr - attrs); | |
426 } | 399 } |
427 | 400 |
428 /* | 401 /* |
429 * Check for conflicting flags, for example, if both PK11_ATTR_PRIVATE | 402 * Check for conflicting flags, for example, if both PK11_ATTR_PRIVATE |
430 * and PK11_ATTR_PUBLIC are set. | 403 * and PK11_ATTR_PUBLIC are set. |
431 */ | 404 */ |
432 PRBool | 405 PRBool pk11_BadAttrFlags(PK11AttrFlags attrFlags) { |
433 pk11_BadAttrFlags(PK11AttrFlags attrFlags) | 406 PK11AttrFlags trueFlags = attrFlags & 0x55555555; |
434 { | 407 PK11AttrFlags falseFlags = (attrFlags >> 1) & 0x55555555; |
435 PK11AttrFlags trueFlags = attrFlags & 0x55555555; | 408 return ((trueFlags & falseFlags) != 0); |
436 PK11AttrFlags falseFlags = (attrFlags >> 1) & 0x55555555; | |
437 return ((trueFlags & falseFlags) != 0); | |
438 } | 409 } |
439 | 410 |
440 /* | 411 /* |
441 * This function may add a maximum of 5 attributes. | 412 * This function may add a maximum of 5 attributes. |
442 * The caller must make sure the attribute flags don't have conflicts. | 413 * The caller must make sure the attribute flags don't have conflicts. |
443 */ | 414 */ |
444 unsigned int | 415 unsigned int pk11_AttrFlagsToAttributes(PK11AttrFlags attrFlags, |
445 pk11_AttrFlagsToAttributes(PK11AttrFlags attrFlags, CK_ATTRIBUTE *attrs, | 416 CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue, |
446 » » » » CK_BBOOL *ckTrue, CK_BBOOL *ckFalse) | 417 CK_BBOOL *ckFalse) { |
447 { | 418 const static CK_ATTRIBUTE_TYPE attrTypes[5] = { |
448 const static CK_ATTRIBUTE_TYPE attrTypes[5] = { | 419 CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_SENSITIVE, CKA_EXTRACTABLE}; |
449 » CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_SENSITIVE, | 420 |
450 » CKA_EXTRACTABLE | 421 const CK_ATTRIBUTE_TYPE *pType = attrTypes; |
451 }; | 422 CK_ATTRIBUTE *attr = attrs; |
452 | 423 PK11AttrFlags test = PK11_ATTR_TOKEN; |
453 const CK_ATTRIBUTE_TYPE *pType» = attrTypes; | 424 |
454 CK_ATTRIBUTE *attr» = attrs; | 425 PR_ASSERT(!pk11_BadAttrFlags(attrFlags)); |
455 PK11AttrFlags test» = PK11_ATTR_TOKEN; | 426 |
456 | 427 /* we test two related bitflags in each iteration */ |
457 PR_ASSERT(!pk11_BadAttrFlags(attrFlags)); | 428 for (; attrFlags && test <= PK11_ATTR_EXTRACTABLE; test <<= 2, ++pType) { |
458 | 429 if (test & attrFlags) { |
459 /* we test two related bitflags in each iteration */ | 430 attrFlags ^= test; |
460 for (; attrFlags && test <= PK11_ATTR_EXTRACTABLE; test <<= 2, ++pType) { | 431 PK11_SETATTRS(attr, *pType, ckTrue, sizeof *ckTrue); |
461 » if (test & attrFlags) { | 432 ++attr; |
462 » attrFlags ^= test; | 433 } else if ((test << 1) & attrFlags) { |
463 » PK11_SETATTRS(attr, *pType, ckTrue, sizeof *ckTrue);· | 434 attrFlags ^= (test << 1); |
464 » ++attr; | 435 PK11_SETATTRS(attr, *pType, ckFalse, sizeof *ckFalse); |
465 » } else if ((test << 1) & attrFlags) { | 436 ++attr; |
466 » attrFlags ^= (test << 1); | |
467 » PK11_SETATTRS(attr, *pType, ckFalse, sizeof *ckFalse);· | |
468 » ++attr; | |
469 » } | |
470 } | 437 } |
471 return (attr - attrs); | 438 } |
| 439 return (attr - attrs); |
472 } | 440 } |
473 | 441 |
474 /* | 442 /* |
475 * Some non-compliant PKCS #11 vendors do not give us the modulus, so actually | 443 * Some non-compliant PKCS #11 vendors do not give us the modulus, so actually |
476 * set up a signature to get the signaure length. | 444 * set up a signature to get the signaure length. |
477 */ | 445 */ |
478 static int | 446 static int pk11_backupGetSignLength(SECKEYPrivateKey *key) { |
479 pk11_backupGetSignLength(SECKEYPrivateKey *key) | 447 PK11SlotInfo *slot = key->pkcs11Slot; |
480 { | 448 CK_MECHANISM mech = {0, NULL, 0}; |
481 PK11SlotInfo *slot = key->pkcs11Slot; | 449 PRBool owner = PR_TRUE; |
482 CK_MECHANISM mech = {0, NULL, 0 }; | 450 CK_SESSION_HANDLE session; |
483 PRBool owner = PR_TRUE; | 451 CK_ULONG len; |
484 CK_SESSION_HANDLE session; | 452 CK_RV crv; |
485 CK_ULONG len; | 453 unsigned char h_data[20] = {0}; |
486 CK_RV crv; | 454 unsigned char buf[20]; /* obviously to small */ |
487 unsigned char h_data[20] = { 0 }; | 455 CK_ULONG smallLen = sizeof(buf); |
488 unsigned char buf[20]; /* obviously to small */ | 456 |
489 CK_ULONG smallLen = sizeof(buf); | 457 mech.mechanism = PK11_MapSignKeyType(key->keyType); |
490 | 458 |
491 mech.mechanism = PK11_MapSignKeyType(key->keyType); | 459 session = pk11_GetNewSession(slot, &owner); |
492 | 460 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); |
493 session = pk11_GetNewSession(slot,&owner); | 461 crv = PK11_GETTAB(slot)->C_SignInit(session, &mech, key->pkcs11ID); |
494 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); | 462 if (crv != CKR_OK) { |
495 crv = PK11_GETTAB(slot)->C_SignInit(session,&mech,key->pkcs11ID); | |
496 if (crv != CKR_OK) { | |
497 » if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | |
498 » pk11_CloseSession(slot,session,owner); | |
499 » PORT_SetError( PK11_MapError(crv) ); | |
500 » return -1; | |
501 } | |
502 len = 0; | |
503 crv = PK11_GETTAB(slot)->C_Sign(session,h_data,sizeof(h_data), | |
504 » » » » » NULL, &len); | |
505 /* now call C_Sign with too small a buffer to clear the session state */ | |
506 (void) PK11_GETTAB(slot)-> | |
507 » » » C_Sign(session,h_data,sizeof(h_data),buf,&smallLen); | |
508 »······· | |
509 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | 463 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
510 pk11_CloseSession(slot,session,owner); | 464 pk11_CloseSession(slot, session, owner); |
511 if (crv != CKR_OK) { | 465 PORT_SetError(PK11_MapError(crv)); |
512 » PORT_SetError( PK11_MapError(crv) ); | 466 return -1; |
513 » return -1; | 467 } |
514 } | 468 len = 0; |
515 return len; | 469 crv = PK11_GETTAB(slot)->C_Sign(session, h_data, sizeof(h_data), NULL, &len); |
| 470 /* now call C_Sign with too small a buffer to clear the session state */ |
| 471 (void)PK11_GETTAB(slot) |
| 472 ->C_Sign(session, h_data, sizeof(h_data), buf, &smallLen); |
| 473 |
| 474 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
| 475 pk11_CloseSession(slot, session, owner); |
| 476 if (crv != CKR_OK) { |
| 477 PORT_SetError(PK11_MapError(crv)); |
| 478 return -1; |
| 479 } |
| 480 return len; |
516 } | 481 } |
517 | 482 |
518 /* | 483 /* |
519 * get the length of a signature object based on the key | 484 * get the length of a signature object based on the key |
520 */ | 485 */ |
521 int | 486 int PK11_SignatureLen(SECKEYPrivateKey *key) { |
522 PK11_SignatureLen(SECKEYPrivateKey *key) | 487 int val; |
523 { | 488 SECItem attributeItem = {siBuffer, NULL, 0}; |
524 int val; | 489 SECStatus rv; |
525 SECItem attributeItem = {siBuffer, NULL, 0}; | 490 int length; |
526 SECStatus rv; | 491 |
527 int length; | 492 switch (key->keyType) { |
528 | |
529 switch (key->keyType) { | |
530 case rsaKey: | 493 case rsaKey: |
531 » val = PK11_GetPrivateModulusLen(key); | 494 val = PK11_GetPrivateModulusLen(key); |
532 » if (val == -1) { | 495 if (val == -1) { |
533 » return pk11_backupGetSignLength(key); | 496 return pk11_backupGetSignLength(key); |
534 » } | 497 } |
535 » return (unsigned long) val; | 498 return (unsigned long)val; |
536 » | 499 |
537 case fortezzaKey: | 500 case fortezzaKey: |
538 » return 40; | 501 return 40; |
539 | 502 |
540 case dsaKey: | 503 case dsaKey: |
541 rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, CKA_SUBPRIME,· | 504 rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, CKA_SUBPRIME, |
542 » » » » NULL, &attributeItem); | 505 NULL, &attributeItem); |
543 if (rv == SECSuccess) { | 506 if (rv == SECSuccess) { |
544 » length = attributeItem.len; | 507 length = attributeItem.len; |
545 » if ((length > 0) && attributeItem.data[0] == 0) { | 508 if ((length > 0) && attributeItem.data[0] == 0) { |
546 » » length--; | 509 length--; |
547 » } | 510 } |
548 » PORT_Free(attributeItem.data); | 511 PORT_Free(attributeItem.data); |
549 » return length*2; | 512 return length * 2; |
550 » } | 513 } |
551 » return pk11_backupGetSignLength(key); | 514 return pk11_backupGetSignLength(key); |
552 | 515 |
553 case ecKey: | 516 case ecKey: |
554 rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, CKA_EC_PARAMS,· | 517 rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, CKA_EC_PARAMS, |
555 » » » » NULL, &attributeItem); | 518 NULL, &attributeItem); |
556 » if (rv == SECSuccess) { | 519 if (rv == SECSuccess) { |
557 » length = SECKEY_ECParamsToBasePointOrderLen(&attributeItem); | 520 length = SECKEY_ECParamsToBasePointOrderLen(&attributeItem); |
558 » PORT_Free(attributeItem.data); | 521 PORT_Free(attributeItem.data); |
559 » if (length != 0) { | 522 if (length != 0) { |
560 » » length = ((length + 7)/8) * 2; | 523 length = ((length + 7) / 8) * 2; |
561 » » return length; | 524 return length; |
562 » } | 525 } |
563 » } | 526 } |
564 » return pk11_backupGetSignLength(key); | 527 return pk11_backupGetSignLength(key); |
565 default: | 528 default: |
566 » break; | 529 break; |
567 } | 530 } |
568 PORT_SetError( SEC_ERROR_INVALID_KEY ); | 531 PORT_SetError(SEC_ERROR_INVALID_KEY); |
569 return 0; | 532 return 0; |
570 } | 533 } |
571 | 534 |
572 /* | 535 /* |
573 * copy a key (or any other object) on a token | 536 * copy a key (or any other object) on a token |
574 */ | 537 */ |
575 CK_OBJECT_HANDLE | 538 CK_OBJECT_HANDLE |
576 PK11_CopyKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE srcObject) | 539 PK11_CopyKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE srcObject) { |
577 { | 540 CK_OBJECT_HANDLE destObject; |
578 CK_OBJECT_HANDLE destObject; | 541 CK_RV crv; |
579 CK_RV crv; | 542 |
580 | 543 PK11_EnterSlotMonitor(slot); |
581 PK11_EnterSlotMonitor(slot); | 544 crv = PK11_GETTAB(slot) |
582 crv = PK11_GETTAB(slot)->C_CopyObject(slot->session,srcObject,NULL,0, | 545 ->C_CopyObject(slot->session, srcObject, NULL, 0, &destObject); |
583 » » » » &destObject); | 546 PK11_ExitSlotMonitor(slot); |
584 PK11_ExitSlotMonitor(slot); | 547 if (crv == CKR_OK) return destObject; |
585 if (crv == CKR_OK) return destObject; | 548 PORT_SetError(PK11_MapError(crv)); |
586 PORT_SetError( PK11_MapError(crv) ); | 549 return CK_INVALID_HANDLE; |
587 return CK_INVALID_HANDLE; | 550 } |
588 } | 551 |
589 | 552 PRBool pk11_FindAttrInTemplate(CK_ATTRIBUTE *attr, unsigned int numAttrs, |
590 PRBool | 553 CK_ATTRIBUTE_TYPE target) { |
591 pk11_FindAttrInTemplate(CK_ATTRIBUTE *attr, unsigned int numAttrs, | 554 for (; numAttrs > 0; ++attr, --numAttrs) { |
592 » » » » » » CK_ATTRIBUTE_TYPE target) | 555 if (attr->type == target) return PR_TRUE; |
593 { | 556 } |
594 for (; numAttrs > 0; ++attr, --numAttrs) { | 557 return PR_FALSE; |
595 » if (attr->type == target) | 558 } |
596 » return PR_TRUE; | 559 |
597 } | |
598 return PR_FALSE; | |
599 } | |
600 »······· | |
601 /* | 560 /* |
602 * Recover the Signed data. We need this because our old verify can't | 561 * Recover the Signed data. We need this because our old verify can't |
603 * figure out which hash algorithm to use until we decryptted this. | 562 * figure out which hash algorithm to use until we decryptted this. |
604 */ | 563 */ |
605 SECStatus | 564 SECStatus PK11_VerifyRecover(SECKEYPublicKey *key, const SECItem *sig, |
606 PK11_VerifyRecover(SECKEYPublicKey *key, const SECItem *sig, | 565 SECItem *dsig, void *wincx) { |
607 » » SECItem *dsig, void *wincx) | 566 PK11SlotInfo *slot = key->pkcs11Slot; |
608 { | 567 CK_OBJECT_HANDLE id = key->pkcs11ID; |
609 PK11SlotInfo *slot = key->pkcs11Slot; | 568 CK_MECHANISM mech = {0, NULL, 0}; |
610 CK_OBJECT_HANDLE id = key->pkcs11ID; | 569 PRBool owner = PR_TRUE; |
611 CK_MECHANISM mech = {0, NULL, 0 }; | 570 CK_SESSION_HANDLE session; |
612 PRBool owner = PR_TRUE; | 571 CK_ULONG len; |
613 CK_SESSION_HANDLE session; | 572 CK_RV crv; |
614 CK_ULONG len; | 573 |
615 CK_RV crv; | 574 mech.mechanism = PK11_MapSignKeyType(key->keyType); |
616 | 575 |
617 mech.mechanism = PK11_MapSignKeyType(key->keyType); | 576 if (slot == NULL) { |
618 | 577 slot = PK11_GetBestSlotWithAttributes(mech.mechanism, CKF_VERIFY_RECOVER, 0, |
| 578 wincx); |
619 if (slot == NULL) { | 579 if (slot == NULL) { |
620 » slot = PK11_GetBestSlotWithAttributes(mech.mechanism, | 580 PORT_SetError(SEC_ERROR_NO_MODULE); |
621 » » » » CKF_VERIFY_RECOVER,0,wincx); | 581 return SECFailure; |
622 » if (slot == NULL) { | |
623 » » PORT_SetError( SEC_ERROR_NO_MODULE ); | |
624 » » return SECFailure; | |
625 » } | |
626 » id = PK11_ImportPublicKey(slot,key,PR_FALSE); | |
627 } else { | |
628 » PK11_ReferenceSlot(slot); | |
629 } | 582 } |
630 | 583 id = PK11_ImportPublicKey(slot, key, PR_FALSE); |
631 if (id == CK_INVALID_HANDLE) { | 584 } else { |
632 » PK11_FreeSlot(slot); | 585 PK11_ReferenceSlot(slot); |
633 » PORT_SetError( SEC_ERROR_BAD_KEY ); | 586 } |
634 » return SECFailure; | 587 |
| 588 if (id == CK_INVALID_HANDLE) { |
| 589 PK11_FreeSlot(slot); |
| 590 PORT_SetError(SEC_ERROR_BAD_KEY); |
| 591 return SECFailure; |
| 592 } |
| 593 |
| 594 session = pk11_GetNewSession(slot, &owner); |
| 595 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); |
| 596 crv = PK11_GETTAB(slot)->C_VerifyRecoverInit(session, &mech, id); |
| 597 if (crv != CKR_OK) { |
| 598 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
| 599 pk11_CloseSession(slot, session, owner); |
| 600 PORT_SetError(PK11_MapError(crv)); |
| 601 PK11_FreeSlot(slot); |
| 602 return SECFailure; |
| 603 } |
| 604 len = dsig->len; |
| 605 crv = PK11_GETTAB(slot) |
| 606 ->C_VerifyRecover(session, sig->data, sig->len, dsig->data, &len); |
| 607 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
| 608 pk11_CloseSession(slot, session, owner); |
| 609 dsig->len = len; |
| 610 if (crv != CKR_OK) { |
| 611 PORT_SetError(PK11_MapError(crv)); |
| 612 PK11_FreeSlot(slot); |
| 613 return SECFailure; |
| 614 } |
| 615 PK11_FreeSlot(slot); |
| 616 return SECSuccess; |
| 617 } |
| 618 |
| 619 /* |
| 620 * verify a signature from its hash. |
| 621 */ |
| 622 SECStatus PK11_Verify(SECKEYPublicKey *key, const SECItem *sig, |
| 623 const SECItem *hash, void *wincx) { |
| 624 PK11SlotInfo *slot = key->pkcs11Slot; |
| 625 CK_OBJECT_HANDLE id = key->pkcs11ID; |
| 626 CK_MECHANISM mech = {0, NULL, 0}; |
| 627 PRBool owner = PR_TRUE; |
| 628 CK_SESSION_HANDLE session; |
| 629 CK_RV crv; |
| 630 |
| 631 mech.mechanism = PK11_MapSignKeyType(key->keyType); |
| 632 |
| 633 if (slot == NULL) { |
| 634 unsigned int length = 0; |
| 635 if ((mech.mechanism == CKM_DSA) && |
| 636 /* 129 is 1024 bits translated to bytes and |
| 637 * padded with an optional '0' to maintain a |
| 638 * positive sign */ |
| 639 (key->u.dsa.params.prime.len > 129)) { |
| 640 /* we need to get a slot that not only can do DSA, but can do DSA2 |
| 641 * key lengths */ |
| 642 length = key->u.dsa.params.prime.len; |
| 643 if (key->u.dsa.params.prime.data[0] == 0) { |
| 644 length--; |
| 645 } |
| 646 /* convert keysize to bits for slot lookup */ |
| 647 length *= 8; |
635 } | 648 } |
636 | 649 slot = PK11_GetBestSlotWithAttributes(mech.mechanism, CKF_VERIFY, length, |
637 session = pk11_GetNewSession(slot,&owner); | 650 wincx); |
638 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); | 651 if (slot == NULL) { |
639 crv = PK11_GETTAB(slot)->C_VerifyRecoverInit(session,&mech,id); | 652 PORT_SetError(SEC_ERROR_NO_MODULE); |
640 if (crv != CKR_OK) { | 653 return SECFailure; |
641 » if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | |
642 » pk11_CloseSession(slot,session,owner); | |
643 » PORT_SetError( PK11_MapError(crv) ); | |
644 » PK11_FreeSlot(slot); | |
645 » return SECFailure; | |
646 } | 654 } |
647 len = dsig->len; | 655 id = PK11_ImportPublicKey(slot, key, PR_FALSE); |
648 crv = PK11_GETTAB(slot)->C_VerifyRecover(session,sig->data, | 656 |
649 » » » » » » sig->len, dsig->data, &len); | 657 } else { |
| 658 PK11_ReferenceSlot(slot); |
| 659 } |
| 660 |
| 661 if (id == CK_INVALID_HANDLE) { |
| 662 PK11_FreeSlot(slot); |
| 663 PORT_SetError(SEC_ERROR_BAD_KEY); |
| 664 return SECFailure; |
| 665 } |
| 666 |
| 667 session = pk11_GetNewSession(slot, &owner); |
| 668 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); |
| 669 crv = PK11_GETTAB(slot)->C_VerifyInit(session, &mech, id); |
| 670 if (crv != CKR_OK) { |
650 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | 671 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
651 pk11_CloseSession(slot,session,owner); | 672 pk11_CloseSession(slot, session, owner); |
652 dsig->len = len; | |
653 if (crv != CKR_OK) { | |
654 » PORT_SetError( PK11_MapError(crv) ); | |
655 » PK11_FreeSlot(slot); | |
656 » return SECFailure; | |
657 } | |
658 PK11_FreeSlot(slot); | 673 PK11_FreeSlot(slot); |
659 return SECSuccess; | 674 PORT_SetError(PK11_MapError(crv)); |
660 } | 675 return SECFailure; |
661 | 676 } |
662 /* | 677 crv = PK11_GETTAB(slot) |
663 * verify a signature from its hash. | 678 ->C_Verify(session, hash->data, hash->len, sig->data, sig->len); |
664 */ | 679 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
665 SECStatus | 680 pk11_CloseSession(slot, session, owner); |
666 PK11_Verify(SECKEYPublicKey *key, const SECItem *sig, const SECItem *hash, | 681 PK11_FreeSlot(slot); |
667 » void *wincx) | 682 if (crv != CKR_OK) { |
668 { | 683 PORT_SetError(PK11_MapError(crv)); |
669 PK11SlotInfo *slot = key->pkcs11Slot; | 684 return SECFailure; |
670 CK_OBJECT_HANDLE id = key->pkcs11ID; | 685 } |
671 CK_MECHANISM mech = {0, NULL, 0 }; | 686 return SECSuccess; |
672 PRBool owner = PR_TRUE; | |
673 CK_SESSION_HANDLE session; | |
674 CK_RV crv; | |
675 | |
676 mech.mechanism = PK11_MapSignKeyType(key->keyType); | |
677 | |
678 if (slot == NULL) { | |
679 » unsigned int length = 0; | |
680 » if ((mech.mechanism == CKM_DSA) &&· | |
681 » » » » /* 129 is 1024 bits translated to bytes and | |
682 » » » » * padded with an optional '0' to maintain a | |
683 » » » » * positive sign */ | |
684 » » » » (key->u.dsa.params.prime.len > 129)) { | |
685 » /* we need to get a slot that not only can do DSA, but can do DSA2 | |
686 » * key lengths */ | |
687 » length = key->u.dsa.params.prime.len; | |
688 » if (key->u.dsa.params.prime.data[0] == 0) { | |
689 » » length --; | |
690 » } | |
691 » /* convert keysize to bits for slot lookup */ | |
692 » length *= 8; | |
693 » } | |
694 » slot = PK11_GetBestSlotWithAttributes(mech.mechanism, | |
695 » » » » » » CKF_VERIFY,length,wincx); | |
696 » if (slot == NULL) { | |
697 » PORT_SetError( SEC_ERROR_NO_MODULE ); | |
698 » return SECFailure; | |
699 » } | |
700 » id = PK11_ImportPublicKey(slot,key,PR_FALSE); | |
701 ············ | |
702 } else { | |
703 » PK11_ReferenceSlot(slot); | |
704 } | |
705 | |
706 if (id == CK_INVALID_HANDLE) { | |
707 » PK11_FreeSlot(slot); | |
708 » PORT_SetError( SEC_ERROR_BAD_KEY ); | |
709 » return SECFailure; | |
710 } | |
711 | |
712 session = pk11_GetNewSession(slot,&owner); | |
713 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); | |
714 crv = PK11_GETTAB(slot)->C_VerifyInit(session,&mech,id); | |
715 if (crv != CKR_OK) { | |
716 » if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | |
717 » pk11_CloseSession(slot,session,owner); | |
718 » PK11_FreeSlot(slot); | |
719 » PORT_SetError( PK11_MapError(crv) ); | |
720 » return SECFailure; | |
721 } | |
722 crv = PK11_GETTAB(slot)->C_Verify(session,hash->data, | |
723 » » » » » hash->len, sig->data, sig->len); | |
724 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | |
725 pk11_CloseSession(slot,session,owner); | |
726 PK11_FreeSlot(slot); | |
727 if (crv != CKR_OK) { | |
728 » PORT_SetError( PK11_MapError(crv) ); | |
729 » return SECFailure; | |
730 } | |
731 return SECSuccess; | |
732 } | 687 } |
733 | 688 |
734 /* | 689 /* |
735 * sign a hash. The algorithm is determined by the key. | 690 * sign a hash. The algorithm is determined by the key. |
736 */ | 691 */ |
737 SECStatus | 692 SECStatus PK11_Sign(SECKEYPrivateKey *key, SECItem *sig, const SECItem *hash) { |
738 PK11_Sign(SECKEYPrivateKey *key, SECItem *sig, const SECItem *hash) | 693 PK11SlotInfo *slot = key->pkcs11Slot; |
739 { | 694 CK_MECHANISM mech = {0, NULL, 0}; |
740 PK11SlotInfo *slot = key->pkcs11Slot; | 695 PRBool owner = PR_TRUE; |
741 CK_MECHANISM mech = {0, NULL, 0 }; | 696 CK_SESSION_HANDLE session; |
742 PRBool owner = PR_TRUE; | 697 PRBool haslock = PR_FALSE; |
743 CK_SESSION_HANDLE session; | 698 CK_ULONG len; |
744 PRBool haslock = PR_FALSE; | 699 CK_RV crv; |
745 CK_ULONG len; | 700 |
746 CK_RV crv; | 701 mech.mechanism = PK11_MapSignKeyType(key->keyType); |
747 | 702 |
748 mech.mechanism = PK11_MapSignKeyType(key->keyType); | 703 if (SECKEY_HAS_ATTRIBUTE_SET(key, CKA_PRIVATE)) { |
749 | 704 PK11_HandlePasswordCheck(slot, key->wincx); |
750 if (SECKEY_HAS_ATTRIBUTE_SET(key,CKA_PRIVATE)) { | 705 } |
751 » PK11_HandlePasswordCheck(slot, key->wincx); | 706 |
752 } | 707 session = pk11_GetNewSession(slot, &owner); |
753 | 708 haslock = (!owner || !(slot->isThreadSafe)); |
754 session = pk11_GetNewSession(slot,&owner); | 709 if (haslock) PK11_EnterSlotMonitor(slot); |
755 haslock = (!owner || !(slot->isThreadSafe)); | 710 crv = PK11_GETTAB(slot)->C_SignInit(session, &mech, key->pkcs11ID); |
756 if (haslock) PK11_EnterSlotMonitor(slot); | 711 if (crv != CKR_OK) { |
757 crv = PK11_GETTAB(slot)->C_SignInit(session,&mech,key->pkcs11ID); | |
758 if (crv != CKR_OK) { | |
759 » if (haslock) PK11_ExitSlotMonitor(slot); | |
760 » pk11_CloseSession(slot,session,owner); | |
761 » PORT_SetError( PK11_MapError(crv) ); | |
762 » return SECFailure; | |
763 } | |
764 | |
765 /* PKCS11 2.20 says if CKA_ALWAYS_AUTHENTICATE then· | |
766 * do C_Login with CKU_CONTEXT_SPECIFIC· | |
767 * between C_SignInit and C_Sign */ | |
768 if (SECKEY_HAS_ATTRIBUTE_SET_LOCK(key, CKA_ALWAYS_AUTHENTICATE, haslock)) { | |
769 » PK11_DoPassword(slot, session, PR_FALSE, key->wincx, haslock, PR_TRUE); | |
770 } | |
771 | |
772 len = sig->len; | |
773 crv = PK11_GETTAB(slot)->C_Sign(session,hash->data, | |
774 » » » » » hash->len, sig->data, &len); | |
775 if (haslock) PK11_ExitSlotMonitor(slot); | |
776 pk11_CloseSession(slot,session,owner); | |
777 sig->len = len; | |
778 if (crv != CKR_OK) { | |
779 » PORT_SetError( PK11_MapError(crv) ); | |
780 » return SECFailure; | |
781 } | |
782 return SECSuccess; | |
783 } | |
784 | |
785 /* | |
786 * sign data with a MAC key. | |
787 */ | |
788 SECStatus | |
789 PK11_SignWithSymKey(PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism, | |
790 » » SECItem *param, SECItem *sig, const SECItem *data) | |
791 { | |
792 PK11SlotInfo *slot = symKey->slot; | |
793 CK_MECHANISM mech = {0, NULL, 0 }; | |
794 PRBool owner = PR_TRUE; | |
795 CK_SESSION_HANDLE session; | |
796 PRBool haslock = PR_FALSE; | |
797 CK_ULONG len; | |
798 CK_RV crv; | |
799 | |
800 mech.mechanism = mechanism; | |
801 if (param) { | |
802 » mech.pParameter = param->data; | |
803 » mech.ulParameterLen = param->len; | |
804 } | |
805 | |
806 session = pk11_GetNewSession(slot,&owner); | |
807 haslock = (!owner || !(slot->isThreadSafe)); | |
808 if (haslock) PK11_EnterSlotMonitor(slot); | |
809 crv = PK11_GETTAB(slot)->C_SignInit(session,&mech,symKey->objectID); | |
810 if (crv != CKR_OK) { | |
811 » if (haslock) PK11_ExitSlotMonitor(slot); | |
812 » pk11_CloseSession(slot,session,owner); | |
813 » PORT_SetError( PK11_MapError(crv) ); | |
814 » return SECFailure; | |
815 } | |
816 | |
817 len = sig->len; | |
818 crv = PK11_GETTAB(slot)->C_Sign(session,data->data, | |
819 » » » » » data->len, sig->data, &len); | |
820 if (haslock) PK11_ExitSlotMonitor(slot); | |
821 pk11_CloseSession(slot,session,owner); | |
822 sig->len = len; | |
823 if (crv != CKR_OK) { | |
824 » PORT_SetError( PK11_MapError(crv) ); | |
825 » return SECFailure; | |
826 } | |
827 return SECSuccess; | |
828 } | |
829 | |
830 SECStatus | |
831 PK11_Decrypt(PK11SymKey *symKey, | |
832 CK_MECHANISM_TYPE mechanism, SECItem *param, | |
833 unsigned char *out, unsigned int *outLen, | |
834 unsigned int maxLen, | |
835 const unsigned char *enc, unsigned encLen) | |
836 { | |
837 PK11SlotInfo *slot = symKey->slot; | |
838 CK_MECHANISM mech = {0, NULL, 0 }; | |
839 CK_ULONG len = maxLen; | |
840 PRBool owner = PR_TRUE; | |
841 CK_SESSION_HANDLE session; | |
842 PRBool haslock = PR_FALSE; | |
843 CK_RV crv; | |
844 | |
845 mech.mechanism = mechanism; | |
846 if (param) { | |
847 » mech.pParameter = param->data; | |
848 » mech.ulParameterLen = param->len; | |
849 } | |
850 | |
851 session = pk11_GetNewSession(slot, &owner); | |
852 haslock = (!owner || !slot->isThreadSafe); | |
853 if (haslock) PK11_EnterSlotMonitor(slot); | |
854 crv = PK11_GETTAB(slot)->C_DecryptInit(session, &mech, symKey->objectID); | |
855 if (crv != CKR_OK) { | |
856 » if (haslock) PK11_ExitSlotMonitor(slot); | |
857 » pk11_CloseSession(slot, session, owner); | |
858 » PORT_SetError( PK11_MapError(crv) ); | |
859 » return SECFailure; | |
860 } | |
861 | |
862 crv = PK11_GETTAB(slot)->C_Decrypt(session, (unsigned char *)enc, encLen, | |
863 out, &len); | |
864 if (haslock) PK11_ExitSlotMonitor(slot); | 712 if (haslock) PK11_ExitSlotMonitor(slot); |
865 pk11_CloseSession(slot, session, owner); | 713 pk11_CloseSession(slot, session, owner); |
866 *outLen = len; | 714 PORT_SetError(PK11_MapError(crv)); |
867 if (crv != CKR_OK) { | 715 return SECFailure; |
868 PORT_SetError( PK11_MapError(crv) ); | 716 } |
869 return SECFailure; | 717 |
| 718 /* PKCS11 2.20 says if CKA_ALWAYS_AUTHENTICATE then |
| 719 * do C_Login with CKU_CONTEXT_SPECIFIC |
| 720 * between C_SignInit and C_Sign */ |
| 721 if (SECKEY_HAS_ATTRIBUTE_SET_LOCK(key, CKA_ALWAYS_AUTHENTICATE, haslock)) { |
| 722 PK11_DoPassword(slot, session, PR_FALSE, key->wincx, haslock, PR_TRUE); |
| 723 } |
| 724 |
| 725 len = sig->len; |
| 726 crv = PK11_GETTAB(slot) |
| 727 ->C_Sign(session, hash->data, hash->len, sig->data, &len); |
| 728 if (haslock) PK11_ExitSlotMonitor(slot); |
| 729 pk11_CloseSession(slot, session, owner); |
| 730 sig->len = len; |
| 731 if (crv != CKR_OK) { |
| 732 PORT_SetError(PK11_MapError(crv)); |
| 733 return SECFailure; |
| 734 } |
| 735 return SECSuccess; |
| 736 } |
| 737 |
| 738 /* |
| 739 * sign data with a MAC key. |
| 740 */ |
| 741 SECStatus PK11_SignWithSymKey(PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism, |
| 742 SECItem *param, SECItem *sig, |
| 743 const SECItem *data) { |
| 744 PK11SlotInfo *slot = symKey->slot; |
| 745 CK_MECHANISM mech = {0, NULL, 0}; |
| 746 PRBool owner = PR_TRUE; |
| 747 CK_SESSION_HANDLE session; |
| 748 PRBool haslock = PR_FALSE; |
| 749 CK_ULONG len; |
| 750 CK_RV crv; |
| 751 |
| 752 mech.mechanism = mechanism; |
| 753 if (param) { |
| 754 mech.pParameter = param->data; |
| 755 mech.ulParameterLen = param->len; |
| 756 } |
| 757 |
| 758 session = pk11_GetNewSession(slot, &owner); |
| 759 haslock = (!owner || !(slot->isThreadSafe)); |
| 760 if (haslock) PK11_EnterSlotMonitor(slot); |
| 761 crv = PK11_GETTAB(slot)->C_SignInit(session, &mech, symKey->objectID); |
| 762 if (crv != CKR_OK) { |
| 763 if (haslock) PK11_ExitSlotMonitor(slot); |
| 764 pk11_CloseSession(slot, session, owner); |
| 765 PORT_SetError(PK11_MapError(crv)); |
| 766 return SECFailure; |
| 767 } |
| 768 |
| 769 len = sig->len; |
| 770 crv = PK11_GETTAB(slot) |
| 771 ->C_Sign(session, data->data, data->len, sig->data, &len); |
| 772 if (haslock) PK11_ExitSlotMonitor(slot); |
| 773 pk11_CloseSession(slot, session, owner); |
| 774 sig->len = len; |
| 775 if (crv != CKR_OK) { |
| 776 PORT_SetError(PK11_MapError(crv)); |
| 777 return SECFailure; |
| 778 } |
| 779 return SECSuccess; |
| 780 } |
| 781 |
| 782 SECStatus PK11_Decrypt(PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism, |
| 783 SECItem *param, unsigned char *out, unsigned int *outLen, |
| 784 unsigned int maxLen, const unsigned char *enc, |
| 785 unsigned encLen) { |
| 786 PK11SlotInfo *slot = symKey->slot; |
| 787 CK_MECHANISM mech = {0, NULL, 0}; |
| 788 CK_ULONG len = maxLen; |
| 789 PRBool owner = PR_TRUE; |
| 790 CK_SESSION_HANDLE session; |
| 791 PRBool haslock = PR_FALSE; |
| 792 CK_RV crv; |
| 793 |
| 794 mech.mechanism = mechanism; |
| 795 if (param) { |
| 796 mech.pParameter = param->data; |
| 797 mech.ulParameterLen = param->len; |
| 798 } |
| 799 |
| 800 session = pk11_GetNewSession(slot, &owner); |
| 801 haslock = (!owner || !slot->isThreadSafe); |
| 802 if (haslock) PK11_EnterSlotMonitor(slot); |
| 803 crv = PK11_GETTAB(slot)->C_DecryptInit(session, &mech, symKey->objectID); |
| 804 if (crv != CKR_OK) { |
| 805 if (haslock) PK11_ExitSlotMonitor(slot); |
| 806 pk11_CloseSession(slot, session, owner); |
| 807 PORT_SetError(PK11_MapError(crv)); |
| 808 return SECFailure; |
| 809 } |
| 810 |
| 811 crv = PK11_GETTAB(slot) |
| 812 ->C_Decrypt(session, (unsigned char *)enc, encLen, out, &len); |
| 813 if (haslock) PK11_ExitSlotMonitor(slot); |
| 814 pk11_CloseSession(slot, session, owner); |
| 815 *outLen = len; |
| 816 if (crv != CKR_OK) { |
| 817 PORT_SetError(PK11_MapError(crv)); |
| 818 return SECFailure; |
| 819 } |
| 820 return SECSuccess; |
| 821 } |
| 822 |
| 823 SECStatus PK11_Encrypt(PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism, |
| 824 SECItem *param, unsigned char *out, unsigned int *outLen, |
| 825 unsigned int maxLen, const unsigned char *data, |
| 826 unsigned int dataLen) { |
| 827 PK11SlotInfo *slot = symKey->slot; |
| 828 CK_MECHANISM mech = {0, NULL, 0}; |
| 829 CK_ULONG len = maxLen; |
| 830 PRBool owner = PR_TRUE; |
| 831 CK_SESSION_HANDLE session; |
| 832 PRBool haslock = PR_FALSE; |
| 833 CK_RV crv; |
| 834 |
| 835 mech.mechanism = mechanism; |
| 836 if (param) { |
| 837 mech.pParameter = param->data; |
| 838 mech.ulParameterLen = param->len; |
| 839 } |
| 840 |
| 841 session = pk11_GetNewSession(slot, &owner); |
| 842 haslock = (!owner || !slot->isThreadSafe); |
| 843 if (haslock) PK11_EnterSlotMonitor(slot); |
| 844 crv = PK11_GETTAB(slot)->C_EncryptInit(session, &mech, symKey->objectID); |
| 845 if (crv != CKR_OK) { |
| 846 if (haslock) PK11_ExitSlotMonitor(slot); |
| 847 pk11_CloseSession(slot, session, owner); |
| 848 PORT_SetError(PK11_MapError(crv)); |
| 849 return SECFailure; |
| 850 } |
| 851 crv = PK11_GETTAB(slot) |
| 852 ->C_Encrypt(session, (unsigned char *)data, dataLen, out, &len); |
| 853 if (haslock) PK11_ExitSlotMonitor(slot); |
| 854 pk11_CloseSession(slot, session, owner); |
| 855 *outLen = len; |
| 856 if (crv != CKR_OK) { |
| 857 PORT_SetError(PK11_MapError(crv)); |
| 858 return SECFailure; |
| 859 } |
| 860 return SECSuccess; |
| 861 } |
| 862 |
| 863 static SECStatus pk11_PrivDecryptRaw(SECKEYPrivateKey *key, unsigned char *data, |
| 864 unsigned *outLen, unsigned int maxLen, |
| 865 const unsigned char *enc, unsigned encLen, |
| 866 CK_MECHANISM_PTR mech) { |
| 867 PK11SlotInfo *slot = key->pkcs11Slot; |
| 868 CK_ULONG out = maxLen; |
| 869 PRBool owner = PR_TRUE; |
| 870 CK_SESSION_HANDLE session; |
| 871 PRBool haslock = PR_FALSE; |
| 872 CK_RV crv; |
| 873 |
| 874 if (key->keyType != rsaKey) { |
| 875 PORT_SetError(SEC_ERROR_INVALID_KEY); |
| 876 return SECFailure; |
| 877 } |
| 878 |
| 879 /* Why do we do a PK11_handle check here? for simple |
| 880 * decryption? .. because the user may have asked for 'ask always' |
| 881 * and this is a private key operation. In practice, thought, it's mute |
| 882 * since only servers wind up using this function */ |
| 883 if (SECKEY_HAS_ATTRIBUTE_SET(key, CKA_PRIVATE)) { |
| 884 PK11_HandlePasswordCheck(slot, key->wincx); |
| 885 } |
| 886 session = pk11_GetNewSession(slot, &owner); |
| 887 haslock = (!owner || !(slot->isThreadSafe)); |
| 888 if (haslock) PK11_EnterSlotMonitor(slot); |
| 889 crv = PK11_GETTAB(slot)->C_DecryptInit(session, mech, key->pkcs11ID); |
| 890 if (crv != CKR_OK) { |
| 891 if (haslock) PK11_ExitSlotMonitor(slot); |
| 892 pk11_CloseSession(slot, session, owner); |
| 893 PORT_SetError(PK11_MapError(crv)); |
| 894 return SECFailure; |
| 895 } |
| 896 |
| 897 /* PKCS11 2.20 says if CKA_ALWAYS_AUTHENTICATE then |
| 898 * do C_Login with CKU_CONTEXT_SPECIFIC |
| 899 * between C_DecryptInit and C_Decrypt |
| 900 * ... But see note above about servers */ |
| 901 if (SECKEY_HAS_ATTRIBUTE_SET_LOCK(key, CKA_ALWAYS_AUTHENTICATE, haslock)) { |
| 902 PK11_DoPassword(slot, session, PR_FALSE, key->wincx, haslock, PR_TRUE); |
| 903 } |
| 904 |
| 905 crv = PK11_GETTAB(slot) |
| 906 ->C_Decrypt(session, (unsigned char *)enc, encLen, data, &out); |
| 907 if (haslock) PK11_ExitSlotMonitor(slot); |
| 908 pk11_CloseSession(slot, session, owner); |
| 909 *outLen = out; |
| 910 if (crv != CKR_OK) { |
| 911 PORT_SetError(PK11_MapError(crv)); |
| 912 return SECFailure; |
| 913 } |
| 914 return SECSuccess; |
| 915 } |
| 916 |
| 917 SECStatus PK11_PubDecryptRaw(SECKEYPrivateKey *key, unsigned char *data, |
| 918 unsigned *outLen, unsigned int maxLen, |
| 919 const unsigned char *enc, unsigned encLen) { |
| 920 CK_MECHANISM mech = {CKM_RSA_X_509, NULL, 0}; |
| 921 return pk11_PrivDecryptRaw(key, data, outLen, maxLen, enc, encLen, &mech); |
| 922 } |
| 923 |
| 924 SECStatus PK11_PrivDecryptPKCS1(SECKEYPrivateKey *key, unsigned char *data, |
| 925 unsigned *outLen, unsigned int maxLen, |
| 926 const unsigned char *enc, unsigned encLen) { |
| 927 CK_MECHANISM mech = {CKM_RSA_PKCS, NULL, 0}; |
| 928 return pk11_PrivDecryptRaw(key, data, outLen, maxLen, enc, encLen, &mech); |
| 929 } |
| 930 |
| 931 static SECStatus pk11_PubEncryptRaw(SECKEYPublicKey *key, unsigned char *out, |
| 932 unsigned int *outLen, unsigned int maxLen, |
| 933 const unsigned char *data, unsigned dataLen, |
| 934 CK_MECHANISM_PTR mech, void *wincx) { |
| 935 PK11SlotInfo *slot; |
| 936 CK_OBJECT_HANDLE id; |
| 937 CK_ULONG len = maxLen; |
| 938 PRBool owner = PR_TRUE; |
| 939 CK_SESSION_HANDLE session; |
| 940 CK_RV crv; |
| 941 |
| 942 slot = PK11_GetBestSlotWithAttributes(mech->mechanism, CKF_ENCRYPT, 0, wincx); |
| 943 if (slot == NULL) { |
| 944 PORT_SetError(SEC_ERROR_NO_MODULE); |
| 945 return SECFailure; |
| 946 } |
| 947 |
| 948 id = PK11_ImportPublicKey(slot, key, PR_FALSE); |
| 949 |
| 950 if (id == CK_INVALID_HANDLE) { |
| 951 PK11_FreeSlot(slot); |
| 952 PORT_SetError(SEC_ERROR_BAD_KEY); |
| 953 return SECFailure; |
| 954 } |
| 955 |
| 956 session = pk11_GetNewSession(slot, &owner); |
| 957 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); |
| 958 crv = PK11_GETTAB(slot)->C_EncryptInit(session, mech, id); |
| 959 if (crv != CKR_OK) { |
| 960 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
| 961 pk11_CloseSession(slot, session, owner); |
| 962 PK11_FreeSlot(slot); |
| 963 PORT_SetError(PK11_MapError(crv)); |
| 964 return SECFailure; |
| 965 } |
| 966 crv = PK11_GETTAB(slot) |
| 967 ->C_Encrypt(session, (unsigned char *)data, dataLen, out, &len); |
| 968 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
| 969 pk11_CloseSession(slot, session, owner); |
| 970 PK11_FreeSlot(slot); |
| 971 *outLen = len; |
| 972 if (crv != CKR_OK) { |
| 973 PORT_SetError(PK11_MapError(crv)); |
| 974 return SECFailure; |
| 975 } |
| 976 return SECSuccess; |
| 977 } |
| 978 |
| 979 SECStatus PK11_PubEncryptRaw(SECKEYPublicKey *key, unsigned char *enc, |
| 980 const unsigned char *data, unsigned dataLen, |
| 981 void *wincx) { |
| 982 CK_MECHANISM mech = {CKM_RSA_X_509, NULL, 0}; |
| 983 unsigned int outLen; |
| 984 if (!key || key->keyType != rsaKey) { |
| 985 PORT_SetError(SEC_ERROR_BAD_KEY); |
| 986 return SECFailure; |
| 987 } |
| 988 outLen = SECKEY_PublicKeyStrength(key); |
| 989 return pk11_PubEncryptRaw(key, enc, &outLen, outLen, data, dataLen, &mech, |
| 990 wincx); |
| 991 } |
| 992 |
| 993 SECStatus PK11_PubEncryptPKCS1(SECKEYPublicKey *key, unsigned char *enc, |
| 994 const unsigned char *data, unsigned dataLen, |
| 995 void *wincx) { |
| 996 CK_MECHANISM mech = {CKM_RSA_PKCS, NULL, 0}; |
| 997 unsigned int outLen; |
| 998 if (!key || key->keyType != rsaKey) { |
| 999 PORT_SetError(SEC_ERROR_BAD_KEY); |
| 1000 return SECFailure; |
| 1001 } |
| 1002 outLen = SECKEY_PublicKeyStrength(key); |
| 1003 return pk11_PubEncryptRaw(key, enc, &outLen, outLen, data, dataLen, &mech, |
| 1004 wincx); |
| 1005 } |
| 1006 |
| 1007 SECStatus PK11_PrivDecrypt(SECKEYPrivateKey *key, CK_MECHANISM_TYPE mechanism, |
| 1008 SECItem *param, unsigned char *out, |
| 1009 unsigned int *outLen, unsigned int maxLen, |
| 1010 const unsigned char *enc, unsigned encLen) { |
| 1011 CK_MECHANISM mech = {mechanism, NULL, 0}; |
| 1012 if (param) { |
| 1013 mech.pParameter = param->data; |
| 1014 mech.ulParameterLen = param->len; |
| 1015 } |
| 1016 return pk11_PrivDecryptRaw(key, out, outLen, maxLen, enc, encLen, &mech); |
| 1017 } |
| 1018 |
| 1019 SECStatus PK11_PubEncrypt(SECKEYPublicKey *key, CK_MECHANISM_TYPE mechanism, |
| 1020 SECItem *param, unsigned char *out, |
| 1021 unsigned int *outLen, unsigned int maxLen, |
| 1022 const unsigned char *data, unsigned dataLen, |
| 1023 void *wincx) { |
| 1024 CK_MECHANISM mech = {mechanism, NULL, 0}; |
| 1025 if (param) { |
| 1026 mech.pParameter = param->data; |
| 1027 mech.ulParameterLen = param->len; |
| 1028 } |
| 1029 return pk11_PubEncryptRaw(key, out, outLen, maxLen, data, dataLen, &mech, |
| 1030 wincx); |
| 1031 } |
| 1032 |
| 1033 SECKEYPrivateKey *PK11_UnwrapPrivKey( |
| 1034 PK11SlotInfo *slot, PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType, |
| 1035 SECItem *param, SECItem *wrappedKey, SECItem *label, SECItem *idValue, |
| 1036 PRBool perm, PRBool sensitive, CK_KEY_TYPE keyType, |
| 1037 CK_ATTRIBUTE_TYPE *usage, int usageCount, void *wincx) { |
| 1038 CK_BBOOL cktrue = CK_TRUE; |
| 1039 CK_BBOOL ckfalse = CK_FALSE; |
| 1040 CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; |
| 1041 CK_ATTRIBUTE keyTemplate[15]; |
| 1042 int templateCount = 0; |
| 1043 CK_OBJECT_HANDLE privKeyID; |
| 1044 CK_MECHANISM mechanism; |
| 1045 CK_ATTRIBUTE *attrs = keyTemplate; |
| 1046 SECItem *param_free = NULL, *ck_id = NULL; |
| 1047 CK_RV crv; |
| 1048 CK_SESSION_HANDLE rwsession; |
| 1049 PK11SymKey *newKey = NULL; |
| 1050 int i; |
| 1051 |
| 1052 if (!slot || !wrappedKey || !idValue) { |
| 1053 /* SET AN ERROR!!! */ |
| 1054 return NULL; |
| 1055 } |
| 1056 |
| 1057 ck_id = PK11_MakeIDFromPubKey(idValue); |
| 1058 if (!ck_id) { |
| 1059 return NULL; |
| 1060 } |
| 1061 |
| 1062 PK11_SETATTRS(attrs, CKA_TOKEN, perm ? &cktrue : &ckfalse, sizeof(cktrue)); |
| 1063 attrs++; |
| 1064 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); |
| 1065 attrs++; |
| 1066 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); |
| 1067 attrs++; |
| 1068 PK11_SETATTRS(attrs, CKA_PRIVATE, sensitive ? &cktrue : &ckfalse, |
| 1069 sizeof(cktrue)); |
| 1070 attrs++; |
| 1071 PK11_SETATTRS(attrs, CKA_SENSITIVE, sensitive ? &cktrue : &ckfalse, |
| 1072 sizeof(cktrue)); |
| 1073 attrs++; |
| 1074 if (label && label->data) { |
| 1075 PK11_SETATTRS(attrs, CKA_LABEL, label->data, label->len); |
| 1076 attrs++; |
| 1077 } |
| 1078 PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len); |
| 1079 attrs++; |
| 1080 for (i = 0; i < usageCount; i++) { |
| 1081 PK11_SETATTRS(attrs, usage[i], &cktrue, sizeof(cktrue)); |
| 1082 attrs++; |
| 1083 } |
| 1084 |
| 1085 if (PK11_IsInternal(slot)) { |
| 1086 PK11_SETATTRS(attrs, CKA_NETSCAPE_DB, idValue->data, idValue->len); |
| 1087 attrs++; |
| 1088 } |
| 1089 |
| 1090 templateCount = attrs - keyTemplate; |
| 1091 PR_ASSERT(templateCount <= (sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE))); |
| 1092 |
| 1093 mechanism.mechanism = wrapType; |
| 1094 if (!param) param = param_free = PK11_ParamFromIV(wrapType, NULL); |
| 1095 if (param) { |
| 1096 mechanism.pParameter = param->data; |
| 1097 mechanism.ulParameterLen = param->len; |
| 1098 } else { |
| 1099 mechanism.pParameter = NULL; |
| 1100 mechanism.ulParameterLen = 0; |
| 1101 } |
| 1102 |
| 1103 if (wrappingKey->slot != slot) { |
| 1104 newKey = pk11_CopyToSlot(slot, wrapType, CKA_UNWRAP, wrappingKey); |
| 1105 } else { |
| 1106 newKey = PK11_ReferenceSymKey(wrappingKey); |
| 1107 } |
| 1108 |
| 1109 if (newKey) { |
| 1110 if (perm) { |
| 1111 /* Get RW Session will either lock the monitor if necessary, |
| 1112 * or return a thread safe session handle, or fail. */ |
| 1113 rwsession = PK11_GetRWSession(slot); |
| 1114 } else { |
| 1115 rwsession = slot->session; |
| 1116 if (rwsession != CK_INVALID_SESSION) PK11_EnterSlotMonitor(slot); |
870 } | 1117 } |
871 return SECSuccess; | 1118 /* This is a lot a work to deal with fussy PKCS #11 modules |
872 } | 1119 * that can't bother to return BAD_DATA when presented with an |
873 | 1120 * invalid session! */ |
874 SECStatus | 1121 if (rwsession == CK_INVALID_SESSION) { |
875 PK11_Encrypt(PK11SymKey *symKey, | 1122 PORT_SetError(SEC_ERROR_BAD_DATA); |
876 CK_MECHANISM_TYPE mechanism, SECItem *param, | 1123 goto loser; |
877 unsigned char *out, unsigned int *outLen, | |
878 unsigned int maxLen, | |
879 const unsigned char *data, unsigned int dataLen) | |
880 { | |
881 PK11SlotInfo *slot = symKey->slot; | |
882 CK_MECHANISM mech = {0, NULL, 0 }; | |
883 CK_ULONG len = maxLen; | |
884 PRBool owner = PR_TRUE; | |
885 CK_SESSION_HANDLE session; | |
886 PRBool haslock = PR_FALSE; | |
887 CK_RV crv; | |
888 | |
889 mech.mechanism = mechanism; | |
890 if (param) { | |
891 » mech.pParameter = param->data; | |
892 » mech.ulParameterLen = param->len; | |
893 } | 1124 } |
894 | 1125 crv = PK11_GETTAB(slot)->C_UnwrapKey( |
895 session = pk11_GetNewSession(slot, &owner); | 1126 rwsession, &mechanism, newKey->objectID, wrappedKey->data, |
896 haslock = (!owner || !slot->isThreadSafe); | 1127 wrappedKey->len, keyTemplate, templateCount, &privKeyID); |
897 if (haslock) PK11_EnterSlotMonitor(slot); | 1128 |
898 crv = PK11_GETTAB(slot)->C_EncryptInit(session, &mech, symKey->objectID); | 1129 if (perm) { |
899 if (crv != CKR_OK) { | 1130 PK11_RestoreROSession(slot, rwsession); |
900 » if (haslock) PK11_ExitSlotMonitor(slot); | 1131 } else { |
901 » pk11_CloseSession(slot,session,owner); | 1132 PK11_ExitSlotMonitor(slot); |
902 » PORT_SetError( PK11_MapError(crv) ); | |
903 » return SECFailure; | |
904 } | 1133 } |
905 crv = PK11_GETTAB(slot)->C_Encrypt(session, (unsigned char *)data, | 1134 PK11_FreeSymKey(newKey); |
906 dataLen, out, &len); | 1135 newKey = NULL; |
907 if (haslock) PK11_ExitSlotMonitor(slot); | 1136 } else { |
908 pk11_CloseSession(slot,session,owner); | 1137 crv = CKR_FUNCTION_NOT_SUPPORTED; |
909 *outLen = len; | 1138 } |
910 if (crv != CKR_OK) { | 1139 |
911 » PORT_SetError( PK11_MapError(crv) ); | 1140 if (ck_id) { |
912 » return SECFailure; | 1141 SECITEM_FreeItem(ck_id, PR_TRUE); |
| 1142 ck_id = NULL; |
| 1143 } |
| 1144 |
| 1145 if (crv != CKR_OK) { |
| 1146 /* we couldn't unwrap the key, use the internal module to do the |
| 1147 * unwrap, then load the new key into the token */ |
| 1148 PK11SlotInfo *int_slot = PK11_GetInternalSlot(); |
| 1149 |
| 1150 if (int_slot && (slot != int_slot)) { |
| 1151 SECKEYPrivateKey *privKey = PK11_UnwrapPrivKey( |
| 1152 int_slot, wrappingKey, wrapType, param, wrappedKey, label, idValue, |
| 1153 PR_FALSE, PR_FALSE, keyType, usage, usageCount, wincx); |
| 1154 if (privKey) { |
| 1155 SECKEYPrivateKey *newPrivKey = |
| 1156 PK11_LoadPrivKey(slot, privKey, NULL, perm, sensitive); |
| 1157 SECKEY_DestroyPrivateKey(privKey); |
| 1158 PK11_FreeSlot(int_slot); |
| 1159 return newPrivKey; |
| 1160 } |
913 } | 1161 } |
914 return SECSuccess; | 1162 if (int_slot) PK11_FreeSlot(int_slot); |
915 } | 1163 PORT_SetError(PK11_MapError(crv)); |
916 | 1164 return NULL; |
917 static SECStatus | 1165 } |
918 pk11_PrivDecryptRaw(SECKEYPrivateKey *key, | 1166 return PK11_MakePrivKey(slot, nullKey, PR_FALSE, privKeyID, wincx); |
919 unsigned char *data, unsigned *outLen, unsigned int maxLen, | |
920 const unsigned char *enc, unsigned encLen, | |
921 CK_MECHANISM_PTR mech) | |
922 { | |
923 PK11SlotInfo *slot = key->pkcs11Slot; | |
924 CK_ULONG out = maxLen; | |
925 PRBool owner = PR_TRUE; | |
926 CK_SESSION_HANDLE session; | |
927 PRBool haslock = PR_FALSE; | |
928 CK_RV crv; | |
929 | |
930 if (key->keyType != rsaKey) { | |
931 PORT_SetError( SEC_ERROR_INVALID_KEY ); | |
932 return SECFailure; | |
933 } | |
934 | |
935 /* Why do we do a PK11_handle check here? for simple | |
936 * decryption? .. because the user may have asked for 'ask always' | |
937 * and this is a private key operation. In practice, thought, it's mute | |
938 * since only servers wind up using this function */ | |
939 if (SECKEY_HAS_ATTRIBUTE_SET(key,CKA_PRIVATE)) { | |
940 PK11_HandlePasswordCheck(slot, key->wincx); | |
941 } | |
942 session = pk11_GetNewSession(slot,&owner); | |
943 haslock = (!owner || !(slot->isThreadSafe)); | |
944 if (haslock) PK11_EnterSlotMonitor(slot); | |
945 crv = PK11_GETTAB(slot)->C_DecryptInit(session, mech, key->pkcs11ID); | |
946 if (crv != CKR_OK) { | |
947 if (haslock) PK11_ExitSlotMonitor(slot); | |
948 pk11_CloseSession(slot,session,owner); | |
949 PORT_SetError( PK11_MapError(crv) ); | |
950 return SECFailure; | |
951 } | |
952 | |
953 /* PKCS11 2.20 says if CKA_ALWAYS_AUTHENTICATE then· | |
954 * do C_Login with CKU_CONTEXT_SPECIFIC· | |
955 * between C_DecryptInit and C_Decrypt | |
956 * ... But see note above about servers */ | |
957 if (SECKEY_HAS_ATTRIBUTE_SET_LOCK(key, CKA_ALWAYS_AUTHENTICATE, haslock)) { | |
958 PK11_DoPassword(slot, session, PR_FALSE, key->wincx, haslock, PR_TRUE); | |
959 } | |
960 | |
961 crv = PK11_GETTAB(slot)->C_Decrypt(session, (unsigned char *)enc, encLen, | |
962 data, &out); | |
963 if (haslock) PK11_ExitSlotMonitor(slot); | |
964 pk11_CloseSession(slot,session,owner); | |
965 *outLen = out; | |
966 if (crv != CKR_OK) { | |
967 PORT_SetError( PK11_MapError(crv) ); | |
968 return SECFailure; | |
969 } | |
970 return SECSuccess; | |
971 } | |
972 | |
973 SECStatus | |
974 PK11_PubDecryptRaw(SECKEYPrivateKey *key, | |
975 unsigned char *data, unsigned *outLen, unsigned int maxLen, | |
976 const unsigned char *enc, unsigned encLen) | |
977 { | |
978 CK_MECHANISM mech = {CKM_RSA_X_509, NULL, 0 }; | |
979 return pk11_PrivDecryptRaw(key, data, outLen, maxLen, enc, encLen, &mech); | |
980 } | |
981 | |
982 SECStatus | |
983 PK11_PrivDecryptPKCS1(SECKEYPrivateKey *key, | |
984 unsigned char *data, unsigned *outLen, unsigned int maxLen
, | |
985 const unsigned char *enc, unsigned encLen) | |
986 { | |
987 CK_MECHANISM mech = {CKM_RSA_PKCS, NULL, 0 }; | |
988 return pk11_PrivDecryptRaw(key, data, outLen, maxLen, enc, encLen, &mech); | |
989 } | |
990 | |
991 static SECStatus | |
992 pk11_PubEncryptRaw(SECKEYPublicKey *key, | |
993 unsigned char *out, unsigned int *outLen, | |
994 unsigned int maxLen, | |
995 const unsigned char *data, unsigned dataLen, | |
996 CK_MECHANISM_PTR mech, void *wincx) | |
997 { | |
998 PK11SlotInfo *slot; | |
999 CK_OBJECT_HANDLE id; | |
1000 CK_ULONG len = maxLen; | |
1001 PRBool owner = PR_TRUE; | |
1002 CK_SESSION_HANDLE session; | |
1003 CK_RV crv; | |
1004 | |
1005 slot = PK11_GetBestSlotWithAttributes(mech->mechanism,CKF_ENCRYPT,0,wincx); | |
1006 if (slot == NULL) { | |
1007 PORT_SetError( SEC_ERROR_NO_MODULE ); | |
1008 return SECFailure; | |
1009 } | |
1010 | |
1011 id = PK11_ImportPublicKey(slot,key,PR_FALSE); | |
1012 | |
1013 if (id == CK_INVALID_HANDLE) { | |
1014 PK11_FreeSlot(slot); | |
1015 PORT_SetError( SEC_ERROR_BAD_KEY ); | |
1016 return SECFailure; | |
1017 } | |
1018 | |
1019 session = pk11_GetNewSession(slot,&owner); | |
1020 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); | |
1021 crv = PK11_GETTAB(slot)->C_EncryptInit(session, mech, id); | |
1022 if (crv != CKR_OK) { | |
1023 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | |
1024 pk11_CloseSession(slot,session,owner); | |
1025 PK11_FreeSlot(slot); | |
1026 PORT_SetError( PK11_MapError(crv) ); | |
1027 return SECFailure; | |
1028 } | |
1029 crv = PK11_GETTAB(slot)->C_Encrypt(session,(unsigned char *)data,dataLen, | |
1030 out,&len); | |
1031 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | |
1032 pk11_CloseSession(slot,session,owner); | |
1033 PK11_FreeSlot(slot); | |
1034 *outLen = len; | |
1035 if (crv != CKR_OK) { | |
1036 PORT_SetError( PK11_MapError(crv) ); | |
1037 return SECFailure; | |
1038 } | |
1039 return SECSuccess; | |
1040 } | |
1041 | |
1042 SECStatus | |
1043 PK11_PubEncryptRaw(SECKEYPublicKey *key, | |
1044 unsigned char *enc, | |
1045 const unsigned char *data, unsigned dataLen, | |
1046 void *wincx) | |
1047 { | |
1048 CK_MECHANISM mech = {CKM_RSA_X_509, NULL, 0 }; | |
1049 unsigned int outLen; | |
1050 if (!key || key->keyType != rsaKey) { | |
1051 PORT_SetError(SEC_ERROR_BAD_KEY); | |
1052 return SECFailure; | |
1053 } | |
1054 outLen = SECKEY_PublicKeyStrength(key); | |
1055 return pk11_PubEncryptRaw(key, enc, &outLen, outLen, data, dataLen, &mech, | |
1056 wincx); | |
1057 } | |
1058 | |
1059 SECStatus | |
1060 PK11_PubEncryptPKCS1(SECKEYPublicKey *key, | |
1061 unsigned char *enc, | |
1062 const unsigned char *data, unsigned dataLen, | |
1063 void *wincx) | |
1064 { | |
1065 CK_MECHANISM mech = {CKM_RSA_PKCS, NULL, 0 }; | |
1066 unsigned int outLen; | |
1067 if (!key || key->keyType != rsaKey) { | |
1068 PORT_SetError(SEC_ERROR_BAD_KEY); | |
1069 return SECFailure; | |
1070 } | |
1071 outLen = SECKEY_PublicKeyStrength(key); | |
1072 return pk11_PubEncryptRaw(key, enc, &outLen, outLen, data, dataLen, &mech, | |
1073 wincx); | |
1074 } | |
1075 | |
1076 SECStatus | |
1077 PK11_PrivDecrypt(SECKEYPrivateKey *key, | |
1078 CK_MECHANISM_TYPE mechanism, SECItem *param, | |
1079 unsigned char *out, unsigned int *outLen, | |
1080 unsigned int maxLen, | |
1081 const unsigned char *enc, unsigned encLen) | |
1082 { | |
1083 CK_MECHANISM mech = { mechanism, NULL, 0 }; | |
1084 if (param) { | |
1085 mech.pParameter = param->data; | |
1086 mech.ulParameterLen = param->len; | |
1087 } | |
1088 return pk11_PrivDecryptRaw(key, out, outLen, maxLen, enc, encLen, &mech); | |
1089 } | |
1090 | |
1091 SECStatus | |
1092 PK11_PubEncrypt(SECKEYPublicKey *key, | |
1093 CK_MECHANISM_TYPE mechanism, SECItem *param, | |
1094 unsigned char *out, unsigned int *outLen, | |
1095 unsigned int maxLen, | |
1096 const unsigned char *data, unsigned dataLen, | |
1097 void *wincx) | |
1098 { | |
1099 CK_MECHANISM mech = { mechanism, NULL, 0 }; | |
1100 if (param) { | |
1101 mech.pParameter = param->data; | |
1102 mech.ulParameterLen = param->len; | |
1103 } | |
1104 return pk11_PubEncryptRaw(key, out, outLen, maxLen, data, dataLen, &mech, | |
1105 wincx); | |
1106 } | |
1107 | |
1108 SECKEYPrivateKey * | |
1109 PK11_UnwrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey, | |
1110 CK_MECHANISM_TYPE wrapType, SECItem *param,· | |
1111 SECItem *wrappedKey, SECItem *label,· | |
1112 SECItem *idValue, PRBool perm, PRBool sensitive, | |
1113 CK_KEY_TYPE keyType, CK_ATTRIBUTE_TYPE *usage, | |
1114 int usageCount, void *wincx) | |
1115 { | |
1116 CK_BBOOL cktrue = CK_TRUE; | |
1117 CK_BBOOL ckfalse = CK_FALSE; | |
1118 CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; | |
1119 CK_ATTRIBUTE keyTemplate[15] ; | |
1120 int templateCount = 0; | |
1121 CK_OBJECT_HANDLE privKeyID; | |
1122 CK_MECHANISM mechanism; | |
1123 CK_ATTRIBUTE *attrs = keyTemplate; | |
1124 SECItem *param_free = NULL, *ck_id = NULL; | |
1125 CK_RV crv; | |
1126 CK_SESSION_HANDLE rwsession; | |
1127 PK11SymKey *newKey = NULL; | |
1128 int i; | |
1129 | |
1130 if(!slot || !wrappedKey || !idValue) { | |
1131 /* SET AN ERROR!!! */ | |
1132 return NULL; | |
1133 } | |
1134 | |
1135 ck_id = PK11_MakeIDFromPubKey(idValue); | |
1136 if(!ck_id) { | |
1137 return NULL; | |
1138 } | |
1139 | |
1140 PK11_SETATTRS(attrs, CKA_TOKEN, perm ? &cktrue : &ckfalse, | |
1141 sizeof(cktrue)); attrs++; | |
1142 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); attrs++; | |
1143 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++; | |
1144 PK11_SETATTRS(attrs, CKA_PRIVATE, sensitive ? &cktrue : &ckfalse, | |
1145 sizeof(cktrue)); attrs++; | |
1146 PK11_SETATTRS(attrs, CKA_SENSITIVE, sensitive ? &cktrue : &ckfalse, | |
1147 sizeof(cktrue)); attrs++; | |
1148 if (label && label->data) { | |
1149 PK11_SETATTRS(attrs, CKA_LABEL, label->data, label->len); attrs++; | |
1150 } | |
1151 PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len); attrs++; | |
1152 for (i=0; i < usageCount; i++) { | |
1153 PK11_SETATTRS(attrs, usage[i], &cktrue, sizeof(cktrue)); attrs++; | |
1154 } | |
1155 | |
1156 if (PK11_IsInternal(slot)) { | |
1157 PK11_SETATTRS(attrs, CKA_NETSCAPE_DB, idValue->data,· | |
1158 idValue->len); attrs++; | |
1159 } | |
1160 | |
1161 templateCount = attrs - keyTemplate; | |
1162 PR_ASSERT(templateCount <= (sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE)) ); | |
1163 | |
1164 mechanism.mechanism = wrapType; | |
1165 if(!param) param = param_free= PK11_ParamFromIV(wrapType, NULL); | |
1166 if(param) { | |
1167 mechanism.pParameter = param->data; | |
1168 mechanism.ulParameterLen = param->len; | |
1169 } else { | |
1170 mechanism.pParameter = NULL; | |
1171 mechanism.ulParameterLen = 0; | |
1172 } | |
1173 | |
1174 if (wrappingKey->slot != slot) { | |
1175 newKey = pk11_CopyToSlot(slot,wrapType,CKA_UNWRAP,wrappingKey); | |
1176 } else { | |
1177 newKey = PK11_ReferenceSymKey(wrappingKey); | |
1178 } | |
1179 | |
1180 if (newKey) { | |
1181 if (perm) { | |
1182 /* Get RW Session will either lock the monitor if necessary,· | |
1183 * or return a thread safe session handle, or fail. */· | |
1184 rwsession = PK11_GetRWSession(slot); | |
1185 } else { | |
1186 rwsession = slot->session; | |
1187 if (rwsession != CK_INVALID_SESSION)· | |
1188 PK11_EnterSlotMonitor(slot); | |
1189 } | |
1190 /* This is a lot a work to deal with fussy PKCS #11 modules | |
1191 * that can't bother to return BAD_DATA when presented with an | |
1192 * invalid session! */ | |
1193 if (rwsession == CK_INVALID_SESSION) { | |
1194 PORT_SetError(SEC_ERROR_BAD_DATA); | |
1195 goto loser; | |
1196 } | |
1197 crv = PK11_GETTAB(slot)->C_UnwrapKey(rwsession, &mechanism,· | |
1198 newKey->objectID, | |
1199 wrappedKey->data,· | |
1200 wrappedKey->len, keyTemplate,· | |
1201 templateCount, &privKeyID); | |
1202 | |
1203 if (perm) { | |
1204 PK11_RestoreROSession(slot, rwsession); | |
1205 } else { | |
1206 PK11_ExitSlotMonitor(slot); | |
1207 } | |
1208 PK11_FreeSymKey(newKey); | |
1209 newKey = NULL; | |
1210 } else { | |
1211 crv = CKR_FUNCTION_NOT_SUPPORTED; | |
1212 } | |
1213 | |
1214 if (ck_id) { | |
1215 SECITEM_FreeItem(ck_id, PR_TRUE); | |
1216 ck_id = NULL; | |
1217 } | |
1218 | |
1219 if (crv != CKR_OK) { | |
1220 /* we couldn't unwrap the key, use the internal module to do the | |
1221 * unwrap, then load the new key into the token */ | |
1222 PK11SlotInfo *int_slot = PK11_GetInternalSlot(); | |
1223 | |
1224 if (int_slot && (slot != int_slot)) { | |
1225 SECKEYPrivateKey *privKey = PK11_UnwrapPrivKey(int_slot, | |
1226 wrappingKey, wrapType, param, wrappedKey, label, | |
1227 idValue, PR_FALSE, PR_FALSE,· | |
1228 keyType, usage, usageCount, wincx); | |
1229 if (privKey) { | |
1230 SECKEYPrivateKey *newPrivKey = PK11_LoadPrivKey(slot,privKey, | |
1231 NULL,perm,sensitive); | |
1232 SECKEY_DestroyPrivateKey(privKey); | |
1233 PK11_FreeSlot(int_slot); | |
1234 return newPrivKey; | |
1235 } | |
1236 } | |
1237 if (int_slot) PK11_FreeSlot(int_slot); | |
1238 PORT_SetError( PK11_MapError(crv) ); | |
1239 return NULL; | |
1240 } | |
1241 return PK11_MakePrivKey(slot, nullKey, PR_FALSE, privKeyID, wincx); | |
1242 | 1167 |
1243 loser: | 1168 loser: |
1244 if (newKey) { | 1169 if (newKey) { |
1245 » PK11_FreeSymKey(newKey); | 1170 PK11_FreeSymKey(newKey); |
1246 } | 1171 } |
1247 if (ck_id) { | 1172 if (ck_id) { |
1248 » SECITEM_FreeItem(ck_id, PR_TRUE); | 1173 SECITEM_FreeItem(ck_id, PR_TRUE); |
1249 } | 1174 } |
1250 return NULL; | 1175 return NULL; |
1251 } | 1176 } |
1252 | 1177 |
1253 /* | 1178 /* |
1254 * Now we're going to wrap a SECKEYPrivateKey with a PK11SymKey | 1179 * Now we're going to wrap a SECKEYPrivateKey with a PK11SymKey |
1255 * The strategy is to get both keys to reside in the same slot, | 1180 * The strategy is to get both keys to reside in the same slot, |
1256 * one that can perform the desired crypto mechanism and then | 1181 * one that can perform the desired crypto mechanism and then |
1257 * call C_WrapKey after all the setup has taken place. | 1182 * call C_WrapKey after all the setup has taken place. |
1258 */ | 1183 */ |
1259 SECStatus | 1184 SECStatus PK11_WrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey, |
1260 PK11_WrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,· | 1185 SECKEYPrivateKey *privKey, |
1261 » » SECKEYPrivateKey *privKey, CK_MECHANISM_TYPE wrapType, | 1186 CK_MECHANISM_TYPE wrapType, SECItem *param, |
1262 » » SECItem *param, SECItem *wrappedKey, void *wincx) | 1187 SECItem *wrappedKey, void *wincx) { |
1263 { | 1188 PK11SlotInfo *privSlot = privKey->pkcs11Slot; /* The slot where |
1264 PK11SlotInfo *privSlot = privKey->pkcs11Slot; /* The slot where | 1189 * the private key |
1265 » » » » » » » * the private key | 1190 * we are going to |
1266 » » » » » » » * we are going to | 1191 * wrap lives. |
1267 » » » » » » » * wrap lives. | 1192 */ |
1268 » » » » » » » */ | 1193 PK11SymKey *newSymKey = NULL; |
1269 PK11SymKey *newSymKey = NULL; | 1194 SECKEYPrivateKey *newPrivKey = NULL; |
1270 SECKEYPrivateKey *newPrivKey = NULL; | 1195 SECItem *param_free = NULL; |
1271 SECItem *param_free = NULL; | 1196 CK_ULONG len = wrappedKey->len; |
1272 CK_ULONG len = wrappedKey->len; | 1197 CK_MECHANISM mech; |
1273 CK_MECHANISM mech; | 1198 CK_RV crv; |
1274 CK_RV crv; | 1199 |
1275 | 1200 if (!privSlot || !PK11_DoesMechanism(privSlot, wrapType)) { |
1276 if (!privSlot || !PK11_DoesMechanism(privSlot, wrapType)) { | 1201 /* Figure out a slot that does the mechanism and try to import |
1277 /* Figure out a slot that does the mechanism and try to import | 1202 * the private key onto that slot. |
1278 » * the private key onto that slot. | 1203 */ |
1279 » */ | 1204 PK11SlotInfo *int_slot = PK11_GetInternalSlot(); |
1280 PK11SlotInfo *int_slot = PK11_GetInternalSlot(); | 1205 |
1281 | 1206 privSlot = int_slot; /* The private key has a new home */ |
1282 » privSlot = int_slot; /* The private key has a new home */ | 1207 newPrivKey = PK11_LoadPrivKey(privSlot, privKey, NULL, PR_FALSE, PR_FALSE); |
1283 » newPrivKey = PK11_LoadPrivKey(privSlot,privKey,NULL,PR_FALSE,PR_FALSE); | 1208 /* newPrivKey has allocated its own reference to the slot, so it's |
1284 » /* newPrivKey has allocated its own reference to the slot, so it's | 1209 * safe until we destroy newPrivkey. |
1285 » * safe until we destroy newPrivkey. | 1210 */ |
1286 » */ | 1211 PK11_FreeSlot(int_slot); |
1287 » PK11_FreeSlot(int_slot); | 1212 if (newPrivKey == NULL) { |
1288 » if (newPrivKey == NULL) { | 1213 return SECFailure; |
1289 » return SECFailure; | |
1290 » } | |
1291 » privKey = newPrivKey; | |
1292 } | 1214 } |
1293 | 1215 privKey = newPrivKey; |
1294 if (privSlot != wrappingKey->slot) { | 1216 } |
1295 newSymKey = pk11_CopyToSlot (privSlot, wrapType, CKA_WRAP,· | 1217 |
1296 » » » » wrappingKey); | 1218 if (privSlot != wrappingKey->slot) { |
1297 » wrappingKey = newSymKey; | 1219 newSymKey = pk11_CopyToSlot(privSlot, wrapType, CKA_WRAP, wrappingKey); |
| 1220 wrappingKey = newSymKey; |
| 1221 } |
| 1222 |
| 1223 if (wrappingKey == NULL) { |
| 1224 if (newPrivKey) { |
| 1225 SECKEY_DestroyPrivateKey(newPrivKey); |
1298 } | 1226 } |
1299 | 1227 return SECFailure; |
1300 if (wrappingKey == NULL) { | 1228 } |
1301 if (newPrivKey) { | 1229 mech.mechanism = wrapType; |
1302 » » SECKEY_DestroyPrivateKey(newPrivKey); | 1230 if (!param) { |
1303 » } | 1231 param = param_free = PK11_ParamFromIV(wrapType, NULL); |
1304 » return SECFailure; | 1232 } |
1305 } | 1233 if (param) { |
1306 mech.mechanism = wrapType; | 1234 mech.pParameter = param->data; |
1307 if (!param) { | 1235 mech.ulParameterLen = param->len; |
1308 param = param_free = PK11_ParamFromIV(wrapType, NULL); | 1236 } else { |
1309 } | 1237 mech.pParameter = NULL; |
1310 if (param) { | 1238 mech.ulParameterLen = 0; |
1311 mech.pParameter = param->data; | 1239 } |
1312 » mech.ulParameterLen = param->len; | 1240 |
1313 } else { | 1241 PK11_EnterSlotMonitor(privSlot); |
1314 mech.pParameter = NULL; | 1242 crv = PK11_GETTAB(privSlot) |
1315 » mech.ulParameterLen = 0; | 1243 ->C_WrapKey(privSlot->session, &mech, wrappingKey->objectID, |
1316 } | 1244 privKey->pkcs11ID, wrappedKey->data, &len); |
1317 | 1245 PK11_ExitSlotMonitor(privSlot); |
1318 PK11_EnterSlotMonitor(privSlot); | 1246 |
1319 crv = PK11_GETTAB(privSlot)->C_WrapKey(privSlot->session, &mech, | 1247 if (newSymKey) { |
1320 » » » » » wrappingKey->objectID,· | 1248 PK11_FreeSymKey(newSymKey); |
1321 » » » » » privKey->pkcs11ID, | 1249 } |
1322 » » » » » wrappedKey->data, &len); | 1250 if (newPrivKey) { |
1323 PK11_ExitSlotMonitor(privSlot); | 1251 SECKEY_DestroyPrivateKey(newPrivKey); |
1324 | 1252 } |
1325 if (newSymKey) { | 1253 if (param_free) { |
1326 PK11_FreeSymKey(newSymKey); | 1254 SECITEM_FreeItem(param_free, PR_TRUE); |
1327 } | 1255 } |
1328 if (newPrivKey) { | 1256 |
1329 SECKEY_DestroyPrivateKey(newPrivKey); | 1257 if (crv != CKR_OK) { |
1330 } | 1258 PORT_SetError(PK11_MapError(crv)); |
1331 if (param_free) { | 1259 return SECFailure; |
1332 » SECITEM_FreeItem(param_free,PR_TRUE); | 1260 } |
1333 } | 1261 |
1334 | 1262 wrappedKey->len = len; |
1335 if (crv != CKR_OK) { | 1263 return SECSuccess; |
1336 PORT_SetError( PK11_MapError(crv) ); | |
1337 » return SECFailure; | |
1338 } | |
1339 | |
1340 wrappedKey->len = len; | |
1341 return SECSuccess; | |
1342 } | 1264 } |
1343 | 1265 |
1344 #if 0 | 1266 #if 0 |
1345 /* | 1267 /* |
1346 * Sample code relating to linked list returned by PK11_FindGenericObjects | 1268 * Sample code relating to linked list returned by PK11_FindGenericObjects |
1347 */ | 1269 */ |
1348 | 1270 |
1349 /* | 1271 /* |
1350 * You can walk the list with the following code: | 1272 * You can walk the list with the following code: |
1351 */ | 1273 */ |
(...skipping 27 matching lines...) Expand all Loading... |
1379 | 1301 |
1380 PK11_DestroyGenericObject(myObj); | 1302 PK11_DestroyGenericObject(myObj); |
1381 #endif /* sample code */ | 1303 #endif /* sample code */ |
1382 | 1304 |
1383 /* | 1305 /* |
1384 * return a linked, non-circular list of generic objects. | 1306 * return a linked, non-circular list of generic objects. |
1385 * If you are only interested | 1307 * If you are only interested |
1386 * in one object, just use the first object in the list. To find the | 1308 * in one object, just use the first object in the list. To find the |
1387 * rest of the list use PK11_GetNextGenericObject() to return the next object. | 1309 * rest of the list use PK11_GetNextGenericObject() to return the next object. |
1388 */ | 1310 */ |
1389 PK11GenericObject * | 1311 PK11GenericObject *PK11_FindGenericObjects(PK11SlotInfo *slot, |
1390 PK11_FindGenericObjects(PK11SlotInfo *slot, CK_OBJECT_CLASS objClass) | 1312 CK_OBJECT_CLASS objClass) { |
1391 { | 1313 CK_ATTRIBUTE template[1]; |
1392 CK_ATTRIBUTE template[1]; | 1314 CK_ATTRIBUTE *attrs = template; |
1393 CK_ATTRIBUTE *attrs = template; | 1315 CK_OBJECT_HANDLE *objectIDs = NULL; |
1394 CK_OBJECT_HANDLE *objectIDs = NULL; | 1316 PK11GenericObject *lastObj = NULL, *obj; |
1395 PK11GenericObject *lastObj = NULL, *obj; | 1317 PK11GenericObject *firstObj = NULL; |
1396 PK11GenericObject *firstObj = NULL; | 1318 int i, count = 0; |
1397 int i, count = 0; | 1319 |
1398 | 1320 PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass)); |
1399 | 1321 attrs++; |
1400 PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass)); attrs++; | 1322 |
1401 | 1323 objectIDs = pk11_FindObjectsByTemplate(slot, template, 1, &count); |
1402 objectIDs = pk11_FindObjectsByTemplate(slot,template,1,&count); | 1324 if (objectIDs == NULL) { |
1403 if (objectIDs == NULL) { | 1325 return NULL; |
1404 » return NULL; | 1326 } |
1405 } | 1327 |
1406 | 1328 /* where we connect our object once we've created it.. */ |
1407 /* where we connect our object once we've created it.. */ | 1329 for (i = 0; i < count; i++) { |
1408 for (i=0; i < count; i++) { | 1330 obj = PORT_New(PK11GenericObject); |
1409 » obj = PORT_New(PK11GenericObject); | 1331 if (!obj) { |
1410 » if ( !obj ) { | 1332 if (firstObj) { |
1411 » if (firstObj) { | 1333 PK11_DestroyGenericObjects(firstObj); |
1412 » » PK11_DestroyGenericObjects(firstObj); | 1334 } |
1413 » } | 1335 PORT_Free(objectIDs); |
1414 » PORT_Free(objectIDs); | 1336 return NULL; |
1415 » return NULL; | 1337 } |
1416 » } | 1338 /* initialize it */ |
1417 » /* initialize it */»···· | 1339 obj->slot = PK11_ReferenceSlot(slot); |
1418 » obj->slot = PK11_ReferenceSlot(slot); | 1340 obj->objectID = objectIDs[i]; |
1419 » obj->objectID = objectIDs[i]; | 1341 obj->next = NULL; |
1420 » obj->next = NULL; | 1342 obj->prev = NULL; |
1421 » obj->prev = NULL; | 1343 |
1422 | 1344 /* link it in */ |
1423 » /* link it in */ | 1345 if (firstObj == NULL) { |
1424 » if (firstObj == NULL) { | 1346 firstObj = obj; |
1425 » firstObj = obj; | 1347 } else { |
1426 » } else { | 1348 PK11_LinkGenericObject(lastObj, obj); |
1427 » PK11_LinkGenericObject(lastObj, obj); | 1349 } |
1428 » } | 1350 lastObj = obj; |
1429 » lastObj = obj; | 1351 } |
1430 } | 1352 PORT_Free(objectIDs); |
1431 PORT_Free(objectIDs); | 1353 return firstObj; |
1432 return firstObj; | |
1433 } | 1354 } |
1434 | 1355 |
1435 /* | 1356 /* |
1436 * get the Next Object in the list. | 1357 * get the Next Object in the list. |
1437 */ | 1358 */ |
1438 PK11GenericObject * | 1359 PK11GenericObject *PK11_GetNextGenericObject(PK11GenericObject *object) { |
1439 PK11_GetNextGenericObject(PK11GenericObject *object) | 1360 return object->next; |
1440 { | 1361 } |
1441 return object->next; | 1362 |
1442 } | 1363 PK11GenericObject *PK11_GetPrevGenericObject(PK11GenericObject *object) { |
1443 | 1364 return object->prev; |
1444 PK11GenericObject * | |
1445 PK11_GetPrevGenericObject(PK11GenericObject *object) | |
1446 { | |
1447 return object->prev; | |
1448 } | 1365 } |
1449 | 1366 |
1450 /* | 1367 /* |
1451 * Link a single object into a new list. | 1368 * Link a single object into a new list. |
1452 * if the object is already in another list, remove it first. | 1369 * if the object is already in another list, remove it first. |
1453 */ | 1370 */ |
1454 SECStatus | 1371 SECStatus PK11_LinkGenericObject(PK11GenericObject *list, |
1455 PK11_LinkGenericObject(PK11GenericObject *list, PK11GenericObject *object) | 1372 PK11GenericObject *object) { |
1456 { | 1373 PK11_UnlinkGenericObject(object); |
1457 PK11_UnlinkGenericObject(object); | 1374 object->prev = list; |
1458 object->prev = list; | 1375 object->next = list->next; |
1459 object->next = list->next; | 1376 list->next = object; |
1460 list->next = object; | 1377 if (object->next != NULL) { |
1461 if (object->next != NULL) { | 1378 object->next->prev = object; |
1462 » object->next->prev = object; | 1379 } |
1463 } | 1380 return SECSuccess; |
1464 return SECSuccess; | |
1465 } | 1381 } |
1466 | 1382 |
1467 /* | 1383 /* |
1468 * remove an object from the list. If the object isn't already in | 1384 * remove an object from the list. If the object isn't already in |
1469 * a list unlink becomes a noop. | 1385 * a list unlink becomes a noop. |
1470 */ | 1386 */ |
1471 SECStatus | 1387 SECStatus PK11_UnlinkGenericObject(PK11GenericObject *object) { |
1472 PK11_UnlinkGenericObject(PK11GenericObject *object) | 1388 if (object->prev != NULL) { |
1473 { | 1389 object->prev->next = object->next; |
1474 if (object->prev != NULL) { | 1390 } |
1475 » object->prev->next = object->next; | 1391 if (object->next != NULL) { |
1476 } | 1392 object->next->prev = object->prev; |
1477 if (object->next != NULL) { | 1393 } |
1478 » object->next->prev = object->prev; | 1394 |
1479 } | 1395 object->next = NULL; |
1480 | 1396 object->prev = NULL; |
1481 object->next = NULL; | 1397 return SECSuccess; |
1482 object->prev = NULL; | |
1483 return SECSuccess; | |
1484 } | 1398 } |
1485 | 1399 |
1486 /* | 1400 /* |
1487 * This function removes a single object from the list and destroys it. | 1401 * This function removes a single object from the list and destroys it. |
1488 * For an already unlinked object there is no difference between | 1402 * For an already unlinked object there is no difference between |
1489 * PK11_DestroyGenericObject and PK11_DestroyGenericObjects | 1403 * PK11_DestroyGenericObject and PK11_DestroyGenericObjects |
1490 */ | 1404 */ |
1491 SECStatus· | 1405 SECStatus PK11_DestroyGenericObject(PK11GenericObject *object) { |
1492 PK11_DestroyGenericObject(PK11GenericObject *object) | 1406 if (object == NULL) { |
1493 { | |
1494 if (object == NULL) { | |
1495 » return SECSuccess; | |
1496 } | |
1497 | |
1498 PK11_UnlinkGenericObject(object); | |
1499 if (object->slot) { | |
1500 » PK11_FreeSlot(object->slot); | |
1501 } | |
1502 PORT_Free(object); | |
1503 return SECSuccess; | 1407 return SECSuccess; |
| 1408 } |
| 1409 |
| 1410 PK11_UnlinkGenericObject(object); |
| 1411 if (object->slot) { |
| 1412 PK11_FreeSlot(object->slot); |
| 1413 } |
| 1414 PORT_Free(object); |
| 1415 return SECSuccess; |
1504 } | 1416 } |
1505 | 1417 |
1506 /* | 1418 /* |
1507 * walk down a link list of generic objects destroying them. | 1419 * walk down a link list of generic objects destroying them. |
1508 * This will destroy all objects in a list that the object is linked into. | 1420 * This will destroy all objects in a list that the object is linked into. |
1509 * (the list is traversed in both directions). | 1421 * (the list is traversed in both directions). |
1510 */ | 1422 */ |
1511 SECStatus· | 1423 SECStatus PK11_DestroyGenericObjects(PK11GenericObject *objects) { |
1512 PK11_DestroyGenericObjects(PK11GenericObject *objects) | 1424 PK11GenericObject *nextObject; |
1513 { | 1425 PK11GenericObject *prevObject; |
1514 PK11GenericObject *nextObject; | 1426 |
1515 PK11GenericObject *prevObject; | 1427 if (objects == NULL) { |
1516 · | 1428 return SECSuccess; |
1517 if (objects == NULL) { | 1429 } |
1518 » return SECSuccess; | 1430 |
1519 } | 1431 nextObject = objects->next; |
1520 | 1432 prevObject = objects->prev; |
| 1433 |
| 1434 /* delete all the objects after it in the list */ |
| 1435 for (; objects; objects = nextObject) { |
1521 nextObject = objects->next; | 1436 nextObject = objects->next; |
| 1437 PK11_DestroyGenericObject(objects); |
| 1438 } |
| 1439 /* delete all the objects before it in the list */ |
| 1440 for (objects = prevObject; objects; objects = prevObject) { |
1522 prevObject = objects->prev; | 1441 prevObject = objects->prev; |
1523 | 1442 PK11_DestroyGenericObject(objects); |
1524 /* delete all the objects after it in the list */ | 1443 } |
1525 for (; objects; objects = nextObject) { | 1444 return SECSuccess; |
1526 » nextObject = objects->next; | 1445 } |
1527 » PK11_DestroyGenericObject(objects); | |
1528 } | |
1529 /* delete all the objects before it in the list */ | |
1530 for (objects = prevObject; objects; objects = prevObject) { | |
1531 » prevObject = objects->prev; | |
1532 » PK11_DestroyGenericObject(objects); | |
1533 } | |
1534 return SECSuccess; | |
1535 } | |
1536 | |
1537 | 1446 |
1538 /* | 1447 /* |
1539 * Hand Create a new object and return the Generic object for our new object. | 1448 * Hand Create a new object and return the Generic object for our new object. |
1540 */ | 1449 */ |
1541 PK11GenericObject * | 1450 PK11GenericObject *PK11_CreateGenericObject(PK11SlotInfo *slot, |
1542 PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate, | 1451 const CK_ATTRIBUTE *pTemplate, |
1543 » » int count, PRBool token) | 1452 int count, PRBool token) { |
1544 { | 1453 CK_OBJECT_HANDLE objectID; |
1545 CK_OBJECT_HANDLE objectID; | 1454 PK11GenericObject *obj; |
1546 PK11GenericObject *obj; | 1455 CK_RV crv; |
1547 CK_RV crv; | 1456 |
1548 | 1457 PK11_EnterSlotMonitor(slot); |
1549 PK11_EnterSlotMonitor(slot); | 1458 crv = PK11_CreateNewObject(slot, slot->session, pTemplate, count, token, |
1550 crv = PK11_CreateNewObject(slot, slot->session, pTemplate, count, | 1459 &objectID); |
1551 » » » token, &objectID); | 1460 PK11_ExitSlotMonitor(slot); |
1552 PK11_ExitSlotMonitor(slot); | 1461 if (crv != CKR_OK) { |
1553 if (crv != CKR_OK) { | 1462 PORT_SetError(PK11_MapError(crv)); |
1554 » PORT_SetError(PK11_MapError(crv)); | 1463 return NULL; |
1555 » return NULL; | 1464 } |
1556 } | 1465 |
1557 | 1466 obj = PORT_New(PK11GenericObject); |
1558 obj = PORT_New(PK11GenericObject); | 1467 if (!obj) { |
1559 if ( !obj ) { | 1468 /* error set by PORT_New */ |
1560 » /* error set by PORT_New */ | 1469 return NULL; |
1561 » return NULL; | 1470 } |
1562 } | 1471 |
1563 | 1472 /* initialize it */ |
1564 /* initialize it */» | 1473 obj->slot = PK11_ReferenceSlot(slot); |
1565 obj->slot = PK11_ReferenceSlot(slot); | 1474 obj->objectID = objectID; |
1566 obj->objectID = objectID; | 1475 obj->next = NULL; |
1567 obj->next = NULL; | 1476 obj->prev = NULL; |
1568 obj->prev = NULL; | 1477 return obj; |
1569 return obj; | |
1570 } | 1478 } |
1571 | 1479 |
1572 /* | 1480 /* |
1573 * Change an attribute on a raw object | 1481 * Change an attribute on a raw object |
1574 */ | 1482 */ |
1575 SECStatus | 1483 SECStatus PK11_WriteRawAttribute(PK11ObjectType objType, void *objSpec, |
1576 PK11_WriteRawAttribute(PK11ObjectType objType, void *objSpec,· | 1484 CK_ATTRIBUTE_TYPE attrType, SECItem *item) { |
1577 » » » » CK_ATTRIBUTE_TYPE attrType, SECItem *item) | 1485 PK11SlotInfo *slot = NULL; |
1578 { | 1486 CK_OBJECT_HANDLE handle; |
1579 PK11SlotInfo *slot = NULL; | 1487 CK_ATTRIBUTE setTemplate; |
1580 CK_OBJECT_HANDLE handle; | 1488 CK_RV crv; |
1581 CK_ATTRIBUTE setTemplate; | 1489 CK_SESSION_HANDLE rwsession; |
1582 CK_RV crv; | 1490 |
1583 CK_SESSION_HANDLE rwsession; | 1491 switch (objType) { |
1584 | |
1585 switch (objType) { | |
1586 case PK11_TypeGeneric: | 1492 case PK11_TypeGeneric: |
1587 » slot = ((PK11GenericObject *)objSpec)->slot; | 1493 slot = ((PK11GenericObject *)objSpec)->slot; |
1588 » handle = ((PK11GenericObject *)objSpec)->objectID; | 1494 handle = ((PK11GenericObject *)objSpec)->objectID; |
1589 » break; | 1495 break; |
1590 case PK11_TypePrivKey: | 1496 case PK11_TypePrivKey: |
1591 » slot = ((SECKEYPrivateKey *)objSpec)->pkcs11Slot; | 1497 slot = ((SECKEYPrivateKey *)objSpec)->pkcs11Slot; |
1592 » handle = ((SECKEYPrivateKey *)objSpec)->pkcs11ID; | 1498 handle = ((SECKEYPrivateKey *)objSpec)->pkcs11ID; |
1593 » break; | 1499 break; |
1594 case PK11_TypePubKey: | 1500 case PK11_TypePubKey: |
1595 » slot = ((SECKEYPublicKey *)objSpec)->pkcs11Slot; | 1501 slot = ((SECKEYPublicKey *)objSpec)->pkcs11Slot; |
1596 » handle = ((SECKEYPublicKey *)objSpec)->pkcs11ID; | 1502 handle = ((SECKEYPublicKey *)objSpec)->pkcs11ID; |
1597 » break; | 1503 break; |
1598 case PK11_TypeSymKey: | 1504 case PK11_TypeSymKey: |
1599 » slot = ((PK11SymKey *)objSpec)->slot; | 1505 slot = ((PK11SymKey *)objSpec)->slot; |
1600 » handle = ((PK11SymKey *)objSpec)->objectID; | 1506 handle = ((PK11SymKey *)objSpec)->objectID; |
1601 » break; | 1507 break; |
1602 case PK11_TypeCert: /* don't handle cert case for now */ | 1508 case PK11_TypeCert: /* don't handle cert case for now */ |
1603 default: | 1509 default: |
1604 » break; | 1510 break; |
1605 } | 1511 } |
1606 if (slot == NULL) { | 1512 if (slot == NULL) { |
1607 » PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE); | 1513 PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE); |
1608 » return SECFailure; | 1514 return SECFailure; |
1609 } | 1515 } |
1610 | 1516 |
1611 PK11_SETATTRS(&setTemplate, attrType, (CK_CHAR *) item->data, item->len); | 1517 PK11_SETATTRS(&setTemplate, attrType, (CK_CHAR *)item->data, item->len); |
1612 rwsession = PK11_GetRWSession(slot); | 1518 rwsession = PK11_GetRWSession(slot); |
1613 if (rwsession == CK_INVALID_SESSION) { | 1519 if (rwsession == CK_INVALID_SESSION) { |
1614 » PORT_SetError(SEC_ERROR_BAD_DATA); | 1520 PORT_SetError(SEC_ERROR_BAD_DATA); |
1615 » return SECFailure; | 1521 return SECFailure; |
1616 } | 1522 } |
1617 crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession, handle, | 1523 crv = PK11_GETTAB(slot) |
1618 » » » &setTemplate, 1); | 1524 ->C_SetAttributeValue(rwsession, handle, &setTemplate, 1); |
1619 PK11_RestoreROSession(slot, rwsession); | 1525 PK11_RestoreROSession(slot, rwsession); |
1620 if (crv != CKR_OK) { | 1526 if (crv != CKR_OK) { |
1621 » PORT_SetError(PK11_MapError(crv)); | 1527 PORT_SetError(PK11_MapError(crv)); |
1622 » return SECFailure; | 1528 return SECFailure; |
1623 } | 1529 } |
1624 return SECSuccess; | 1530 return SECSuccess; |
1625 } | 1531 } |
1626 | 1532 |
1627 | 1533 SECStatus PK11_ReadRawAttribute(PK11ObjectType objType, void *objSpec, |
1628 SECStatus | 1534 CK_ATTRIBUTE_TYPE attrType, SECItem *item) { |
1629 PK11_ReadRawAttribute(PK11ObjectType objType, void *objSpec,· | 1535 PK11SlotInfo *slot = NULL; |
1630 » » » » CK_ATTRIBUTE_TYPE attrType, SECItem *item) | 1536 CK_OBJECT_HANDLE handle; |
1631 { | 1537 |
1632 PK11SlotInfo *slot = NULL; | 1538 switch (objType) { |
1633 CK_OBJECT_HANDLE handle; | |
1634 | |
1635 switch (objType) { | |
1636 case PK11_TypeGeneric: | 1539 case PK11_TypeGeneric: |
1637 » slot = ((PK11GenericObject *)objSpec)->slot; | 1540 slot = ((PK11GenericObject *)objSpec)->slot; |
1638 » handle = ((PK11GenericObject *)objSpec)->objectID; | 1541 handle = ((PK11GenericObject *)objSpec)->objectID; |
1639 » break; | 1542 break; |
1640 case PK11_TypePrivKey: | 1543 case PK11_TypePrivKey: |
1641 » slot = ((SECKEYPrivateKey *)objSpec)->pkcs11Slot; | 1544 slot = ((SECKEYPrivateKey *)objSpec)->pkcs11Slot; |
1642 » handle = ((SECKEYPrivateKey *)objSpec)->pkcs11ID; | 1545 handle = ((SECKEYPrivateKey *)objSpec)->pkcs11ID; |
1643 » break; | 1546 break; |
1644 case PK11_TypePubKey: | 1547 case PK11_TypePubKey: |
1645 » slot = ((SECKEYPublicKey *)objSpec)->pkcs11Slot; | 1548 slot = ((SECKEYPublicKey *)objSpec)->pkcs11Slot; |
1646 » handle = ((SECKEYPublicKey *)objSpec)->pkcs11ID; | 1549 handle = ((SECKEYPublicKey *)objSpec)->pkcs11ID; |
1647 » break; | 1550 break; |
1648 case PK11_TypeSymKey: | 1551 case PK11_TypeSymKey: |
1649 » slot = ((PK11SymKey *)objSpec)->slot; | 1552 slot = ((PK11SymKey *)objSpec)->slot; |
1650 » handle = ((PK11SymKey *)objSpec)->objectID; | 1553 handle = ((PK11SymKey *)objSpec)->objectID; |
1651 » break; | 1554 break; |
1652 case PK11_TypeCert: /* don't handle cert case for now */ | 1555 case PK11_TypeCert: /* don't handle cert case for now */ |
1653 default: | 1556 default: |
1654 » break; | 1557 break; |
1655 } | 1558 } |
1656 if (slot == NULL) { | 1559 if (slot == NULL) { |
1657 » PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE); | 1560 PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE); |
1658 » return SECFailure; | 1561 return SECFailure; |
1659 } | 1562 } |
1660 | 1563 |
1661 return PK11_ReadAttribute(slot, handle, attrType, NULL, item); | 1564 return PK11_ReadAttribute(slot, handle, attrType, NULL, item); |
1662 } | 1565 } |
1663 | |
1664 | 1566 |
1665 /* | 1567 /* |
1666 * return the object handle that matches the template | 1568 * return the object handle that matches the template |
1667 */ | 1569 */ |
1668 CK_OBJECT_HANDLE | 1570 CK_OBJECT_HANDLE |
1669 pk11_FindObjectByTemplate(PK11SlotInfo *slot,CK_ATTRIBUTE *theTemplate,int tsize
) | 1571 pk11_FindObjectByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *theTemplate, |
1670 { | 1572 int tsize) { |
1671 CK_OBJECT_HANDLE object; | 1573 CK_OBJECT_HANDLE object; |
1672 CK_RV crv = CKR_SESSION_HANDLE_INVALID; | 1574 CK_RV crv = CKR_SESSION_HANDLE_INVALID; |
1673 CK_ULONG objectCount; | 1575 CK_ULONG objectCount; |
1674 | 1576 |
1675 /* | 1577 /* |
1676 * issue the find | 1578 * issue the find |
1677 */ | 1579 */ |
1678 PK11_EnterSlotMonitor(slot); | 1580 PK11_EnterSlotMonitor(slot); |
1679 if (slot->session != CK_INVALID_SESSION) { | 1581 if (slot->session != CK_INVALID_SESSION) { |
1680 » crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session,· | 1582 crv = |
1681 » theTemplate, tsize); | 1583 PK11_GETTAB(slot)->C_FindObjectsInit(slot->session, theTemplate, tsize); |
1682 } | 1584 } |
| 1585 if (crv != CKR_OK) { |
| 1586 PK11_ExitSlotMonitor(slot); |
| 1587 PORT_SetError(PK11_MapError(crv)); |
| 1588 return CK_INVALID_HANDLE; |
| 1589 } |
| 1590 |
| 1591 crv = |
| 1592 PK11_GETTAB(slot)->C_FindObjects(slot->session, &object, 1, &objectCount); |
| 1593 PK11_GETTAB(slot)->C_FindObjectsFinal(slot->session); |
| 1594 PK11_ExitSlotMonitor(slot); |
| 1595 if ((crv != CKR_OK) || (objectCount < 1)) { |
| 1596 /* shouldn't use SSL_ERROR... here */ |
| 1597 PORT_SetError(crv != CKR_OK ? PK11_MapError(crv) |
| 1598 : SSL_ERROR_NO_CERTIFICATE); |
| 1599 return CK_INVALID_HANDLE; |
| 1600 } |
| 1601 |
| 1602 /* blow up if the PKCS #11 module returns us and invalid object handle */ |
| 1603 PORT_Assert(object != CK_INVALID_HANDLE); |
| 1604 return object; |
| 1605 } |
| 1606 |
| 1607 /* |
| 1608 * return all the object handles that matches the template |
| 1609 */ |
| 1610 CK_OBJECT_HANDLE *pk11_FindObjectsByTemplate(PK11SlotInfo *slot, |
| 1611 CK_ATTRIBUTE *findTemplate, |
| 1612 int templCount, |
| 1613 int *object_count) { |
| 1614 CK_OBJECT_HANDLE *objID = NULL; |
| 1615 CK_ULONG returned_count = 0; |
| 1616 CK_RV crv = CKR_SESSION_HANDLE_INVALID; |
| 1617 |
| 1618 PK11_EnterSlotMonitor(slot); |
| 1619 if (slot->session != CK_INVALID_SESSION) { |
| 1620 crv = PK11_GETTAB(slot) |
| 1621 ->C_FindObjectsInit(slot->session, findTemplate, templCount); |
| 1622 } |
| 1623 if (crv != CKR_OK) { |
| 1624 PK11_ExitSlotMonitor(slot); |
| 1625 PORT_SetError(PK11_MapError(crv)); |
| 1626 *object_count = -1; |
| 1627 return NULL; |
| 1628 } |
| 1629 |
| 1630 /* |
| 1631 * collect all the Matching Objects |
| 1632 */ |
| 1633 do { |
| 1634 CK_OBJECT_HANDLE *oldObjID = objID; |
| 1635 |
| 1636 if (objID == NULL) { |
| 1637 objID = (CK_OBJECT_HANDLE *)PORT_Alloc( |
| 1638 sizeof(CK_OBJECT_HANDLE) * (*object_count + PK11_SEARCH_CHUNKSIZE)); |
| 1639 } else { |
| 1640 objID = (CK_OBJECT_HANDLE *)PORT_Realloc( |
| 1641 objID, |
| 1642 sizeof(CK_OBJECT_HANDLE) * (*object_count + PK11_SEARCH_CHUNKSIZE)); |
| 1643 } |
| 1644 |
| 1645 if (objID == NULL) { |
| 1646 if (oldObjID) PORT_Free(oldObjID); |
| 1647 break; |
| 1648 } |
| 1649 crv = PK11_GETTAB(slot)->C_FindObjects(slot->session, &objID[*object_count], |
| 1650 PK11_SEARCH_CHUNKSIZE, |
| 1651 &returned_count); |
1683 if (crv != CKR_OK) { | 1652 if (crv != CKR_OK) { |
1684 PK11_ExitSlotMonitor(slot); | 1653 PORT_SetError(PK11_MapError(crv)); |
1685 » PORT_SetError( PK11_MapError(crv) ); | 1654 PORT_Free(objID); |
1686 » return CK_INVALID_HANDLE; | 1655 objID = NULL; |
1687 } | 1656 break; |
1688 | 1657 } |
1689 crv=PK11_GETTAB(slot)->C_FindObjects(slot->session,&object,1,&objectCount); | 1658 *object_count += returned_count; |
1690 PK11_GETTAB(slot)->C_FindObjectsFinal(slot->session); | 1659 } while (returned_count == PK11_SEARCH_CHUNKSIZE); |
1691 PK11_ExitSlotMonitor(slot); | 1660 |
1692 if ((crv != CKR_OK) || (objectCount < 1)) { | 1661 PK11_GETTAB(slot)->C_FindObjectsFinal(slot->session); |
1693 » /* shouldn't use SSL_ERROR... here */ | 1662 PK11_ExitSlotMonitor(slot); |
1694 » PORT_SetError( crv != CKR_OK ? PK11_MapError(crv) : | 1663 |
1695 » » » » » » SSL_ERROR_NO_CERTIFICATE); | 1664 if (objID && (*object_count == 0)) { |
1696 » return CK_INVALID_HANDLE; | 1665 PORT_Free(objID); |
1697 } | 1666 return NULL; |
1698 | 1667 } |
1699 /* blow up if the PKCS #11 module returns us and invalid object handle */ | 1668 if (objID == NULL) *object_count = -1; |
1700 PORT_Assert(object != CK_INVALID_HANDLE); | 1669 return objID; |
1701 return object; | |
1702 }· | |
1703 | |
1704 /* | |
1705 * return all the object handles that matches the template | |
1706 */ | |
1707 CK_OBJECT_HANDLE * | |
1708 pk11_FindObjectsByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate, | |
1709 int templCount, int *object_count)· | |
1710 { | |
1711 CK_OBJECT_HANDLE *objID = NULL; | |
1712 CK_ULONG returned_count = 0; | |
1713 CK_RV crv = CKR_SESSION_HANDLE_INVALID; | |
1714 | |
1715 PK11_EnterSlotMonitor(slot); | |
1716 if (slot->session != CK_INVALID_SESSION) { | |
1717 » crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session,· | |
1718 » findTemplate, templCount); | |
1719 } | |
1720 if (crv != CKR_OK) { | |
1721 » PK11_ExitSlotMonitor(slot); | |
1722 » PORT_SetError( PK11_MapError(crv) ); | |
1723 » *object_count = -1; | |
1724 » return NULL; | |
1725 } | |
1726 | |
1727 | |
1728 /* | |
1729 * collect all the Matching Objects | |
1730 */ | |
1731 do { | |
1732 » CK_OBJECT_HANDLE *oldObjID = objID; | |
1733 | |
1734 » if (objID == NULL) { | |
1735 » objID = (CK_OBJECT_HANDLE *) PORT_Alloc(sizeof(CK_OBJECT_HANDLE)* | |
1736 » » » » (*object_count+ PK11_SEARCH_CHUNKSIZE)); | |
1737 » } else { | |
1738 » objID = (CK_OBJECT_HANDLE *) PORT_Realloc(objID, | |
1739 » » sizeof(CK_OBJECT_HANDLE)*(*object_count+PK11_SEARCH_CHUNKSIZE)); | |
1740 » } | |
1741 | |
1742 » if (objID == NULL) { | |
1743 » if (oldObjID) PORT_Free(oldObjID); | |
1744 » break; | |
1745 » } | |
1746 » crv = PK11_GETTAB(slot)->C_FindObjects(slot->session, | |
1747 » » &objID[*object_count],PK11_SEARCH_CHUNKSIZE,&returned_count); | |
1748 » if (crv != CKR_OK) { | |
1749 » PORT_SetError( PK11_MapError(crv) ); | |
1750 » PORT_Free(objID); | |
1751 » objID = NULL; | |
1752 » break; | |
1753 » } | |
1754 » *object_count += returned_count; | |
1755 } while (returned_count == PK11_SEARCH_CHUNKSIZE); | |
1756 | |
1757 PK11_GETTAB(slot)->C_FindObjectsFinal(slot->session); | |
1758 PK11_ExitSlotMonitor(slot); | |
1759 | |
1760 if (objID && (*object_count == 0)) { | |
1761 » PORT_Free(objID); | |
1762 » return NULL; | |
1763 } | |
1764 if (objID == NULL) *object_count = -1; | |
1765 return objID; | |
1766 } | 1670 } |
1767 /* | 1671 /* |
1768 * given a PKCS #11 object, match it's peer based on the KeyID. searchID | 1672 * given a PKCS #11 object, match it's peer based on the KeyID. searchID |
1769 * is typically a privateKey or a certificate while the peer is the opposite | 1673 * is typically a privateKey or a certificate while the peer is the opposite |
1770 */ | 1674 */ |
1771 CK_OBJECT_HANDLE | 1675 CK_OBJECT_HANDLE |
1772 PK11_MatchItem(PK11SlotInfo *slot, CK_OBJECT_HANDLE searchID, | 1676 PK11_MatchItem(PK11SlotInfo *slot, CK_OBJECT_HANDLE searchID, |
1773 » » » » » » CK_OBJECT_CLASS matchclass) | 1677 CK_OBJECT_CLASS matchclass) { |
1774 { | 1678 CK_ATTRIBUTE theTemplate[] = {{CKA_ID, NULL, 0}, {CKA_CLASS, NULL, 0}}; |
1775 CK_ATTRIBUTE theTemplate[] = { | 1679 /* if you change the array, change the variable below as well */ |
1776 » { CKA_ID, NULL, 0 }, | 1680 CK_ATTRIBUTE *keyclass = &theTemplate[1]; |
1777 » { CKA_CLASS, NULL, 0 } | 1681 int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]); |
1778 }; | 1682 /* if you change the array, change the variable below as well */ |
1779 /* if you change the array, change the variable below as well */ | 1683 CK_OBJECT_HANDLE peerID; |
1780 CK_ATTRIBUTE *keyclass = &theTemplate[1]; | 1684 CK_OBJECT_HANDLE parent; |
1781 int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); | 1685 PLArenaPool *arena; |
1782 /* if you change the array, change the variable below as well */ | 1686 CK_RV crv; |
1783 CK_OBJECT_HANDLE peerID; | 1687 |
1784 CK_OBJECT_HANDLE parent; | 1688 /* now we need to create space for the public key */ |
1785 PLArenaPool *arena; | 1689 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
1786 CK_RV crv; | 1690 if (arena == NULL) return CK_INVALID_HANDLE; |
1787 | 1691 |
1788 /* now we need to create space for the public key */ | 1692 crv = PK11_GetAttributes(arena, slot, searchID, theTemplate, tsize); |
1789 arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE); | 1693 if (crv != CKR_OK) { |
1790 if (arena == NULL) return CK_INVALID_HANDLE; | 1694 PORT_FreeArena(arena, PR_FALSE); |
1791 | 1695 PORT_SetError(PK11_MapError(crv)); |
1792 crv = PK11_GetAttributes(arena,slot,searchID,theTemplate,tsize); | 1696 return CK_INVALID_HANDLE; |
| 1697 } |
| 1698 |
| 1699 if ((theTemplate[0].ulValueLen == 0) || (theTemplate[0].ulValueLen == -1)) { |
| 1700 PORT_FreeArena(arena, PR_FALSE); |
| 1701 if (matchclass == CKO_CERTIFICATE) |
| 1702 PORT_SetError(SEC_ERROR_BAD_KEY); |
| 1703 else |
| 1704 PORT_SetError(SEC_ERROR_NO_KEY); |
| 1705 return CK_INVALID_HANDLE; |
| 1706 } |
| 1707 |
| 1708 /* |
| 1709 * issue the find |
| 1710 */ |
| 1711 parent = *(CK_OBJECT_CLASS *)(keyclass->pValue); |
| 1712 *(CK_OBJECT_CLASS *)(keyclass->pValue) = matchclass; |
| 1713 |
| 1714 peerID = pk11_FindObjectByTemplate(slot, theTemplate, tsize); |
| 1715 PORT_FreeArena(arena, PR_FALSE); |
| 1716 |
| 1717 return peerID; |
| 1718 } |
| 1719 |
| 1720 /* |
| 1721 * count the number of objects that match the template. |
| 1722 */ |
| 1723 int PK11_NumberObjectsFor(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate, |
| 1724 int templCount) { |
| 1725 CK_OBJECT_HANDLE objID[PK11_SEARCH_CHUNKSIZE]; |
| 1726 int object_count = 0; |
| 1727 CK_ULONG returned_count = 0; |
| 1728 CK_RV crv = CKR_SESSION_HANDLE_INVALID; |
| 1729 |
| 1730 PK11_EnterSlotMonitor(slot); |
| 1731 if (slot->session != CK_INVALID_SESSION) { |
| 1732 crv = PK11_GETTAB(slot) |
| 1733 ->C_FindObjectsInit(slot->session, findTemplate, templCount); |
| 1734 } |
| 1735 if (crv != CKR_OK) { |
| 1736 PK11_ExitSlotMonitor(slot); |
| 1737 PORT_SetError(PK11_MapError(crv)); |
| 1738 return object_count; |
| 1739 } |
| 1740 |
| 1741 /* |
| 1742 * collect all the Matching Objects |
| 1743 */ |
| 1744 do { |
| 1745 crv = PK11_GETTAB(slot)->C_FindObjects( |
| 1746 slot->session, objID, PK11_SEARCH_CHUNKSIZE, &returned_count); |
1793 if (crv != CKR_OK) { | 1747 if (crv != CKR_OK) { |
1794 » PORT_FreeArena(arena,PR_FALSE); | 1748 PORT_SetError(PK11_MapError(crv)); |
1795 » PORT_SetError( PK11_MapError(crv) ); | 1749 break; |
1796 » return CK_INVALID_HANDLE; | 1750 } |
1797 } | 1751 object_count += returned_count; |
1798 | 1752 } while (returned_count == PK11_SEARCH_CHUNKSIZE); |
1799 if ((theTemplate[0].ulValueLen == 0) || (theTemplate[0].ulValueLen == -1)) { | 1753 |
1800 » PORT_FreeArena(arena,PR_FALSE); | 1754 PK11_GETTAB(slot)->C_FindObjectsFinal(slot->session); |
1801 » if (matchclass == CKO_CERTIFICATE) | 1755 PK11_ExitSlotMonitor(slot); |
1802 » PORT_SetError(SEC_ERROR_BAD_KEY); | 1756 return object_count; |
1803 » else | |
1804 » PORT_SetError(SEC_ERROR_NO_KEY); | |
1805 » return CK_INVALID_HANDLE; | |
1806 } | |
1807 »······· | |
1808 »······· | |
1809 | |
1810 /* | |
1811 * issue the find | |
1812 */ | |
1813 parent = *(CK_OBJECT_CLASS *)(keyclass->pValue); | |
1814 *(CK_OBJECT_CLASS *)(keyclass->pValue) = matchclass; | |
1815 | |
1816 peerID = pk11_FindObjectByTemplate(slot,theTemplate,tsize); | |
1817 PORT_FreeArena(arena,PR_FALSE); | |
1818 | |
1819 return peerID; | |
1820 } | |
1821 | |
1822 /* | |
1823 * count the number of objects that match the template. | |
1824 */ | |
1825 int | |
1826 PK11_NumberObjectsFor(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,· | |
1827 » » » » » » » int templCount) | |
1828 { | |
1829 CK_OBJECT_HANDLE objID[PK11_SEARCH_CHUNKSIZE]; | |
1830 int object_count = 0; | |
1831 CK_ULONG returned_count = 0; | |
1832 CK_RV crv = CKR_SESSION_HANDLE_INVALID; | |
1833 | |
1834 PK11_EnterSlotMonitor(slot); | |
1835 if (slot->session != CK_INVALID_SESSION) { | |
1836 » crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session, | |
1837 » » » » » » findTemplate, templCount); | |
1838 } | |
1839 if (crv != CKR_OK) { | |
1840 PK11_ExitSlotMonitor(slot); | |
1841 » PORT_SetError( PK11_MapError(crv) ); | |
1842 » return object_count; | |
1843 } | |
1844 | |
1845 /* | |
1846 * collect all the Matching Objects | |
1847 */ | |
1848 do { | |
1849 » crv = PK11_GETTAB(slot)->C_FindObjects(slot->session, objID,· | |
1850 » PK11_SEARCH_CHUNKSIZE,· | |
1851 » » » » » &returned_count); | |
1852 » if (crv != CKR_OK) { | |
1853 » PORT_SetError( PK11_MapError(crv) ); | |
1854 » break; | |
1855 » } | |
1856 » object_count += returned_count; | |
1857 } while (returned_count == PK11_SEARCH_CHUNKSIZE); | |
1858 | |
1859 PK11_GETTAB(slot)->C_FindObjectsFinal(slot->session); | |
1860 PK11_ExitSlotMonitor(slot); | |
1861 return object_count; | |
1862 } | 1757 } |
1863 | 1758 |
1864 /* | 1759 /* |
1865 * Traverse all the objects in a given slot. | 1760 * Traverse all the objects in a given slot. |
1866 */ | 1761 */ |
1867 SECStatus | 1762 SECStatus PK11_TraverseSlot(PK11SlotInfo *slot, void *arg) { |
1868 PK11_TraverseSlot(PK11SlotInfo *slot, void *arg) | 1763 int i; |
1869 { | 1764 CK_OBJECT_HANDLE *objID = NULL; |
1870 int i; | 1765 int object_count = 0; |
1871 CK_OBJECT_HANDLE *objID = NULL; | 1766 pk11TraverseSlot *slotcb = (pk11TraverseSlot *)arg; |
1872 int object_count = 0; | 1767 |
1873 pk11TraverseSlot *slotcb = (pk11TraverseSlot*) arg; | 1768 objID = pk11_FindObjectsByTemplate(slot, slotcb->findTemplate, |
1874 | 1769 slotcb->templateCount, &object_count); |
1875 objID = pk11_FindObjectsByTemplate(slot,slotcb->findTemplate, | 1770 |
1876 » » slotcb->templateCount,&object_count); | 1771 /*Actually this isn't a failure... there just were no objs to be found*/ |
1877 | 1772 if (object_count == 0) { |
1878 /*Actually this isn't a failure... there just were no objs to be found*/ | 1773 return SECSuccess; |
1879 if (object_count == 0) { | 1774 } |
1880 » return SECSuccess; | 1775 |
1881 } | 1776 if (objID == NULL) { |
1882 | 1777 return SECFailure; |
| 1778 } |
| 1779 |
| 1780 for (i = 0; i < object_count; i++) { |
| 1781 (*slotcb->callback)(slot, objID[i], slotcb->callbackArg); |
| 1782 } |
| 1783 PORT_Free(objID); |
| 1784 return SECSuccess; |
| 1785 } |
| 1786 |
| 1787 /* |
| 1788 * Traverse all the objects in all slots. |
| 1789 */ |
| 1790 SECStatus pk11_TraverseAllSlots(SECStatus (*callback)(PK11SlotInfo *, void *), |
| 1791 void *arg, PRBool forceLogin, void *wincx) { |
| 1792 PK11SlotList *list; |
| 1793 PK11SlotListElement *le; |
| 1794 SECStatus rv; |
| 1795 |
| 1796 /* get them all! */ |
| 1797 list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, wincx); |
| 1798 if (list == NULL) return SECFailure; |
| 1799 |
| 1800 /* look at each slot and authenticate as necessary */ |
| 1801 for (le = list->head; le; le = le->next) { |
| 1802 if (forceLogin) { |
| 1803 rv = pk11_AuthenticateUnfriendly(le->slot, PR_FALSE, wincx); |
| 1804 if (rv != SECSuccess) { |
| 1805 continue; |
| 1806 } |
| 1807 } |
| 1808 if (callback) { |
| 1809 (*callback)(le->slot, arg); |
| 1810 } |
| 1811 } |
| 1812 |
| 1813 PK11_FreeSlotList(list); |
| 1814 |
| 1815 return SECSuccess; |
| 1816 } |
| 1817 |
| 1818 CK_OBJECT_HANDLE *PK11_FindObjectsFromNickname(char *nickname, |
| 1819 PK11SlotInfo **slotptr, |
| 1820 CK_OBJECT_CLASS objclass, |
| 1821 int *returnCount, void *wincx) { |
| 1822 char *tokenName; |
| 1823 char *delimit; |
| 1824 PK11SlotInfo *slot; |
| 1825 CK_OBJECT_HANDLE *objID; |
| 1826 CK_ATTRIBUTE findTemplate[] = {{CKA_LABEL, NULL, 0}, {CKA_CLASS, NULL, 0}, }; |
| 1827 int findCount = sizeof(findTemplate) / sizeof(findTemplate[0]); |
| 1828 SECStatus rv; |
| 1829 PK11_SETATTRS(&findTemplate[1], CKA_CLASS, &objclass, sizeof(objclass)); |
| 1830 |
| 1831 *slotptr = slot = NULL; |
| 1832 *returnCount = 0; |
| 1833 /* first find the slot associated with this nickname */ |
| 1834 if ((delimit = PORT_Strchr(nickname, ':')) != NULL) { |
| 1835 int len = delimit - nickname; |
| 1836 tokenName = (char *)PORT_Alloc(len + 1); |
| 1837 PORT_Memcpy(tokenName, nickname, len); |
| 1838 tokenName[len] = 0; |
| 1839 |
| 1840 slot = *slotptr = PK11_FindSlotByName(tokenName); |
| 1841 PORT_Free(tokenName); |
| 1842 /* if we couldn't find a slot, assume the nickname is an internal cert |
| 1843 * with no proceding slot name */ |
| 1844 if (slot == NULL) { |
| 1845 slot = *slotptr = PK11_GetInternalKeySlot(); |
| 1846 } else { |
| 1847 nickname = delimit + 1; |
| 1848 } |
| 1849 } else { |
| 1850 *slotptr = slot = PK11_GetInternalKeySlot(); |
| 1851 } |
| 1852 if (slot == NULL) { |
| 1853 return CK_INVALID_HANDLE; |
| 1854 } |
| 1855 |
| 1856 rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx); |
| 1857 if (rv != SECSuccess) { |
| 1858 PK11_FreeSlot(slot); |
| 1859 *slotptr = NULL; |
| 1860 return CK_INVALID_HANDLE; |
| 1861 } |
| 1862 |
| 1863 findTemplate[0].pValue = nickname; |
| 1864 findTemplate[0].ulValueLen = PORT_Strlen(nickname); |
| 1865 objID = |
| 1866 pk11_FindObjectsByTemplate(slot, findTemplate, findCount, returnCount); |
| 1867 if (objID == NULL) { |
| 1868 /* PKCS #11 isn't clear on whether or not the NULL is |
| 1869 * stored in the template.... try the find again with the |
| 1870 * full null terminated string. */ |
| 1871 findTemplate[0].ulValueLen += 1; |
| 1872 objID = |
| 1873 pk11_FindObjectsByTemplate(slot, findTemplate, findCount, returnCount); |
1883 if (objID == NULL) { | 1874 if (objID == NULL) { |
1884 » return SECFailure; | 1875 /* Well that's the best we can do. It's just not here */ |
1885 } | 1876 /* what about faked nicknames? */ |
1886 | 1877 PK11_FreeSlot(slot); |
1887 for (i=0; i < object_count; i++) { | 1878 *slotptr = NULL; |
1888 » (*slotcb->callback)(slot,objID[i],slotcb->callbackArg); | 1879 *returnCount = 0; |
1889 } | 1880 } |
1890 PORT_Free(objID); | 1881 } |
1891 return SECSuccess; | 1882 |
1892 } | 1883 return objID; |
1893 | 1884 } |
1894 /* | 1885 |
1895 * Traverse all the objects in all slots. | 1886 SECItem *pk11_GetLowLevelKeyFromHandle(PK11SlotInfo *slot, |
1896 */ | 1887 CK_OBJECT_HANDLE handle) { |
1897 SECStatus | 1888 CK_ATTRIBUTE theTemplate[] = {{CKA_ID, NULL, 0}, }; |
1898 pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *),· | 1889 int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]); |
1899 » » » » void *arg, PRBool forceLogin, void *wincx) { | 1890 CK_RV crv; |
1900 PK11SlotList *list; | 1891 SECItem *item; |
1901 PK11SlotListElement *le; | 1892 |
1902 SECStatus rv; | 1893 item = SECITEM_AllocItem(NULL, NULL, 0); |
1903 | 1894 |
1904 /* get them all! */ | 1895 if (item == NULL) { |
1905 list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_FALSE,wincx); | 1896 return NULL; |
1906 if (list == NULL) return SECFailure; | 1897 } |
1907 | 1898 |
1908 /* look at each slot and authenticate as necessary */ | 1899 crv = PK11_GetAttributes(NULL, slot, handle, theTemplate, tsize); |
1909 for (le = list->head ; le; le = le->next) { | 1900 if (crv != CKR_OK) { |
1910 » if (forceLogin) { | 1901 SECITEM_FreeItem(item, PR_TRUE); |
1911 » rv = pk11_AuthenticateUnfriendly(le->slot, PR_FALSE, wincx); | 1902 PORT_SetError(PK11_MapError(crv)); |
1912 » if (rv != SECSuccess) { | 1903 return NULL; |
1913 » » continue; | 1904 } |
1914 » } | 1905 |
1915 » } | 1906 item->data = (unsigned char *)theTemplate[0].pValue; |
1916 » if (callback) { | 1907 item->len = theTemplate[0].ulValueLen; |
1917 » (*callback)(le->slot,arg); | 1908 |
1918 » } | 1909 return item; |
1919 } | 1910 } |
1920 | |
1921 PK11_FreeSlotList(list); | |
1922 | |
1923 return SECSuccess; | |
1924 } | |
1925 | |
1926 CK_OBJECT_HANDLE * | |
1927 PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr, | |
1928 » » CK_OBJECT_CLASS objclass, int *returnCount, void *wincx) | |
1929 { | |
1930 char *tokenName; | |
1931 char *delimit; | |
1932 PK11SlotInfo *slot; | |
1933 CK_OBJECT_HANDLE *objID; | |
1934 CK_ATTRIBUTE findTemplate[] = { | |
1935 » { CKA_LABEL, NULL, 0}, | |
1936 » { CKA_CLASS, NULL, 0}, | |
1937 }; | |
1938 int findCount = sizeof(findTemplate)/sizeof(findTemplate[0]); | |
1939 SECStatus rv; | |
1940 PK11_SETATTRS(&findTemplate[1], CKA_CLASS, &objclass, sizeof(objclass)); | |
1941 | |
1942 *slotptr = slot = NULL; | |
1943 *returnCount = 0; | |
1944 /* first find the slot associated with this nickname */ | |
1945 if ((delimit = PORT_Strchr(nickname,':')) != NULL) { | |
1946 » int len = delimit - nickname; | |
1947 » tokenName = (char*)PORT_Alloc(len+1); | |
1948 » PORT_Memcpy(tokenName,nickname,len); | |
1949 » tokenName[len] = 0; | |
1950 | |
1951 slot = *slotptr = PK11_FindSlotByName(tokenName); | |
1952 PORT_Free(tokenName); | |
1953 » /* if we couldn't find a slot, assume the nickname is an internal cert | |
1954 » * with no proceding slot name */ | |
1955 » if (slot == NULL) { | |
1956 » » slot = *slotptr = PK11_GetInternalKeySlot(); | |
1957 » } else { | |
1958 » » nickname = delimit+1; | |
1959 » } | |
1960 } else { | |
1961 » *slotptr = slot = PK11_GetInternalKeySlot(); | |
1962 } | |
1963 if (slot == NULL) { | |
1964 return CK_INVALID_HANDLE; | |
1965 } | |
1966 | |
1967 rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx); | |
1968 if (rv != SECSuccess) { | |
1969 » PK11_FreeSlot(slot); | |
1970 » *slotptr = NULL; | |
1971 » return CK_INVALID_HANDLE; | |
1972 } | |
1973 | |
1974 findTemplate[0].pValue = nickname; | |
1975 findTemplate[0].ulValueLen = PORT_Strlen(nickname); | |
1976 objID = pk11_FindObjectsByTemplate(slot,findTemplate,findCount,returnCount); | |
1977 if (objID == NULL) { | |
1978 » /* PKCS #11 isn't clear on whether or not the NULL is | |
1979 » * stored in the template.... try the find again with the | |
1980 » * full null terminated string. */ | |
1981 » findTemplate[0].ulValueLen += 1; | |
1982 objID = pk11_FindObjectsByTemplate(slot,findTemplate,findCount, | |
1983 » » » » » » » » returnCount); | |
1984 » if (objID == NULL) { | |
1985 » /* Well that's the best we can do. It's just not here */ | |
1986 » /* what about faked nicknames? */ | |
1987 » PK11_FreeSlot(slot); | |
1988 » *slotptr = NULL; | |
1989 » *returnCount = 0; | |
1990 » } | |
1991 } | |
1992 | |
1993 return objID; | |
1994 } | |
1995 | |
1996 SECItem * | |
1997 pk11_GetLowLevelKeyFromHandle(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle)· | |
1998 { | |
1999 CK_ATTRIBUTE theTemplate[] = { | |
2000 » { CKA_ID, NULL, 0 }, | |
2001 }; | |
2002 int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); | |
2003 CK_RV crv; | |
2004 SECItem *item; | |
2005 | |
2006 item = SECITEM_AllocItem(NULL, NULL, 0); | |
2007 | |
2008 if (item == NULL) { | |
2009 » return NULL; | |
2010 } | |
2011 | |
2012 crv = PK11_GetAttributes(NULL,slot,handle,theTemplate,tsize); | |
2013 if (crv != CKR_OK) { | |
2014 » SECITEM_FreeItem(item,PR_TRUE); | |
2015 » PORT_SetError( PK11_MapError(crv) ); | |
2016 » return NULL; | |
2017 } | |
2018 | |
2019 item->data = (unsigned char*) theTemplate[0].pValue; | |
2020 item->len =theTemplate[0].ulValueLen; | |
2021 | |
2022 return item; | |
2023 } | |
2024 | |
OLD | NEW |