update credits
[LibreOffice.git] / libxmlsec / src / tokens.c
blob25c1fb08d0a727bfc4d69c70db8cc397150e14d5
1 /**
2 * XMLSec library
4 * This is free software; see Copyright file in the source
5 * distribution for preciese wording.
7 * Copyright..................................
9 * Contributor(s): _____________________________
13 /**
14 * In order to ensure that particular crypto operation is performed on
15 * particular crypto device, a subclass of xmlSecList is used to store slot and
16 * mechanism information.
18 * In the list, a slot is bound with a mechanism. If the mechanism is available,
19 * this mechanism only can perform on the slot; otherwise, it can perform on
20 * every eligibl slot in the list.
22 * When try to find a slot for a particular mechanism, the slot bound with
23 * available mechanism will be looked up firstly.
25 #include "globals.h"
26 #include <string.h>
28 #include <xmlsec/xmlsec.h>
29 #include <xmlsec/errors.h>
30 #include <xmlsec/list.h>
32 #include <xmlsec/nss/tokens.h>
34 int
35 xmlSecNssKeySlotSetMechList(
36 xmlSecNssKeySlotPtr keySlot ,
37 CK_MECHANISM_TYPE_PTR mechanismList
38 ) {
39 int counter ;
41 xmlSecAssert2( keySlot != NULL , -1 ) ;
43 if( keySlot->mechanismList != CK_NULL_PTR ) {
44 xmlFree( keySlot->mechanismList ) ;
46 for( counter = 0 ; *( mechanismList + counter ) != CKM_INVALID_MECHANISM ; counter ++ ) ;
47 keySlot->mechanismList = ( CK_MECHANISM_TYPE_PTR )xmlMalloc( ( counter + 1 ) * sizeof( CK_MECHANISM_TYPE ) ) ;
48 if( keySlot->mechanismList == NULL ) {
49 xmlSecError( XMLSEC_ERRORS_HERE ,
50 NULL ,
51 NULL ,
52 XMLSEC_ERRORS_R_XMLSEC_FAILED ,
53 XMLSEC_ERRORS_NO_MESSAGE ) ;
54 return( -1 );
56 for( ; counter >= 0 ; counter -- )
57 *( keySlot->mechanismList + counter ) = *( mechanismList + counter ) ;
60 return( 0 );
63 int
64 xmlSecNssKeySlotEnableMech(
65 xmlSecNssKeySlotPtr keySlot ,
66 CK_MECHANISM_TYPE mechanism
67 ) {
68 int counter ;
69 CK_MECHANISM_TYPE_PTR newList ;
71 xmlSecAssert2( keySlot != NULL , -1 ) ;
73 if( mechanism != CKM_INVALID_MECHANISM ) {
74 for( counter = 0 ; *( keySlot->mechanismList + counter ) != CKM_INVALID_MECHANISM ; counter ++ ) ;
75 newList = ( CK_MECHANISM_TYPE_PTR )xmlMalloc( ( counter + 1 + 1 ) * sizeof( CK_MECHANISM_TYPE ) ) ;
76 if( newList == NULL ) {
77 xmlSecError( XMLSEC_ERRORS_HERE ,
78 NULL ,
79 NULL ,
80 XMLSEC_ERRORS_R_XMLSEC_FAILED ,
81 XMLSEC_ERRORS_NO_MESSAGE ) ;
82 return( -1 );
84 *( newList + counter + 1 ) = CKM_INVALID_MECHANISM ;
85 *( newList + counter ) = mechanism ;
86 for( counter -= 1 ; counter >= 0 ; counter -- )
87 *( newList + counter ) = *( keySlot->mechanismList + counter ) ;
89 xmlFree( keySlot->mechanismList ) ;
90 keySlot->mechanismList = newList ;
93 return(0);
96 int
97 xmlSecNssKeySlotDisableMech(
98 xmlSecNssKeySlotPtr keySlot ,
99 CK_MECHANISM_TYPE mechanism
101 int counter ;
103 xmlSecAssert2( keySlot != NULL , -1 ) ;
105 for( counter = 0 ; *( keySlot->mechanismList + counter ) != CKM_INVALID_MECHANISM ; counter ++ ) {
106 if( *( keySlot->mechanismList + counter ) == mechanism ) {
107 for( ; *( keySlot->mechanismList + counter ) != CKM_INVALID_MECHANISM ; counter ++ ) {
108 *( keySlot->mechanismList + counter ) = *( keySlot->mechanismList + counter + 1 ) ;
111 break ;
115 return(0);
118 CK_MECHANISM_TYPE_PTR
119 xmlSecNssKeySlotGetMechList(
120 xmlSecNssKeySlotPtr keySlot
122 if( keySlot != NULL )
123 return keySlot->mechanismList ;
124 else
125 return NULL ;
129 xmlSecNssKeySlotSetSlot(
130 xmlSecNssKeySlotPtr keySlot ,
131 PK11SlotInfo* slot
133 xmlSecAssert2( keySlot != NULL , -1 ) ;
135 if( slot != NULL && keySlot->slot != slot ) {
136 if( keySlot->slot != NULL )
137 PK11_FreeSlot( keySlot->slot ) ;
139 if( keySlot->mechanismList != NULL ) {
140 xmlFree( keySlot->mechanismList ) ;
141 keySlot->mechanismList = NULL ;
144 keySlot->slot = PK11_ReferenceSlot( slot ) ;
147 return(0);
151 xmlSecNssKeySlotInitialize(
152 xmlSecNssKeySlotPtr keySlot ,
153 PK11SlotInfo* slot
155 xmlSecAssert2( keySlot != NULL , -1 ) ;
156 xmlSecAssert2( keySlot->slot == NULL , -1 ) ;
157 xmlSecAssert2( keySlot->mechanismList == NULL , -1 ) ;
159 if( slot != NULL ) {
160 keySlot->slot = PK11_ReferenceSlot( slot ) ;
163 return(0);
166 void
167 xmlSecNssKeySlotFinalize(
168 xmlSecNssKeySlotPtr keySlot
170 xmlSecAssert( keySlot != NULL ) ;
172 if( keySlot->mechanismList != NULL ) {
173 xmlFree( keySlot->mechanismList ) ;
174 keySlot->mechanismList = NULL ;
177 if( keySlot->slot != NULL ) {
178 PK11_FreeSlot( keySlot->slot ) ;
179 keySlot->slot = NULL ;
184 PK11SlotInfo*
185 xmlSecNssKeySlotGetSlot(
186 xmlSecNssKeySlotPtr keySlot
188 if( keySlot != NULL )
189 return keySlot->slot ;
190 else
191 return NULL ;
194 xmlSecNssKeySlotPtr
195 xmlSecNssKeySlotCreate() {
196 xmlSecNssKeySlotPtr keySlot ;
198 /* Allocates a new xmlSecNssKeySlot and fill the fields */
199 keySlot = ( xmlSecNssKeySlotPtr )xmlMalloc( sizeof( xmlSecNssKeySlot ) ) ;
200 if( keySlot == NULL ) {
201 xmlSecError( XMLSEC_ERRORS_HERE ,
202 NULL ,
203 NULL ,
204 XMLSEC_ERRORS_R_XMLSEC_FAILED ,
205 XMLSEC_ERRORS_NO_MESSAGE ) ;
206 return( NULL );
208 memset( keySlot, 0, sizeof( xmlSecNssKeySlot ) ) ;
210 return( keySlot ) ;
214 xmlSecNssKeySlotCopy(
215 xmlSecNssKeySlotPtr newKeySlot ,
216 xmlSecNssKeySlotPtr keySlot
218 CK_MECHANISM_TYPE_PTR mech ;
219 int counter ;
221 xmlSecAssert2( newKeySlot != NULL , -1 ) ;
222 xmlSecAssert2( keySlot != NULL , -1 ) ;
224 if( keySlot->slot != NULL && newKeySlot->slot != keySlot->slot ) {
225 if( newKeySlot->slot != NULL )
226 PK11_FreeSlot( newKeySlot->slot ) ;
228 newKeySlot->slot = PK11_ReferenceSlot( keySlot->slot ) ;
231 if( keySlot->mechanismList != CK_NULL_PTR ) {
232 xmlFree( newKeySlot->mechanismList ) ;
234 for( counter = 0 ; *( keySlot->mechanismList + counter ) != CKM_INVALID_MECHANISM ; counter ++ ) ;
235 newKeySlot->mechanismList = ( CK_MECHANISM_TYPE_PTR )xmlMalloc( ( counter + 1 ) * sizeof( CK_MECHANISM_TYPE ) ) ;
236 if( newKeySlot->mechanismList == NULL ) {
237 xmlSecError( XMLSEC_ERRORS_HERE ,
238 NULL ,
239 NULL ,
240 XMLSEC_ERRORS_R_XMLSEC_FAILED ,
241 XMLSEC_ERRORS_NO_MESSAGE ) ;
242 return( -1 );
244 for( ; counter >= 0 ; counter -- )
245 *( newKeySlot->mechanismList + counter ) = *( keySlot->mechanismList + counter ) ;
248 return( 0 );
251 xmlSecNssKeySlotPtr
252 xmlSecNssKeySlotDuplicate(
253 xmlSecNssKeySlotPtr keySlot
255 xmlSecNssKeySlotPtr newKeySlot ;
256 int ret ;
258 xmlSecAssert2( keySlot != NULL , NULL ) ;
260 newKeySlot = xmlSecNssKeySlotCreate() ;
261 if( newKeySlot == NULL ) {
262 xmlSecError( XMLSEC_ERRORS_HERE ,
263 NULL ,
264 NULL ,
265 XMLSEC_ERRORS_R_XMLSEC_FAILED ,
266 XMLSEC_ERRORS_NO_MESSAGE ) ;
267 return( NULL );
270 if( xmlSecNssKeySlotCopy( newKeySlot, keySlot ) < 0 ) {
271 xmlSecError( XMLSEC_ERRORS_HERE ,
272 NULL ,
273 NULL ,
274 XMLSEC_ERRORS_R_XMLSEC_FAILED ,
275 XMLSEC_ERRORS_NO_MESSAGE ) ;
276 return( NULL );
279 return( newKeySlot );
282 void
283 xmlSecNssKeySlotDestroy(
284 xmlSecNssKeySlotPtr keySlot
286 xmlSecAssert( keySlot != NULL ) ;
288 if( keySlot->mechanismList != NULL )
289 xmlFree( keySlot->mechanismList ) ;
291 if( keySlot->slot != NULL )
292 PK11_FreeSlot( keySlot->slot ) ;
294 xmlFree( keySlot ) ;
298 xmlSecNssKeySlotBindMech(
299 xmlSecNssKeySlotPtr keySlot ,
300 CK_MECHANISM_TYPE type
302 int counter ;
304 xmlSecAssert2( keySlot != NULL , 0 ) ;
305 xmlSecAssert2( keySlot->slot != NULL , 0 ) ;
306 xmlSecAssert2( type != CKM_INVALID_MECHANISM , 0 ) ;
308 for( counter = 0 ; *( keySlot->mechanismList + counter ) != CKM_INVALID_MECHANISM ; counter ++ ) {
309 if( *( keySlot->mechanismList + counter ) == type )
310 return(1) ;
313 return( 0 ) ;
317 xmlSecNssKeySlotSupportMech(
318 xmlSecNssKeySlotPtr keySlot ,
319 CK_MECHANISM_TYPE type
321 xmlSecAssert2( keySlot != NULL , 0 ) ;
322 xmlSecAssert2( keySlot->slot != NULL , 0 ) ;
323 xmlSecAssert2( type != CKM_INVALID_MECHANISM , 0 ) ;
325 if( PK11_DoesMechanism( keySlot->slot , type ) == PR_TRUE ) {
326 return(1);
327 } else
328 return(0);
331 void
332 xmlSecNssKeySlotDebugDump(
333 xmlSecNssKeySlotPtr keySlot ,
334 FILE* output
336 xmlSecAssert( keySlot != NULL ) ;
337 xmlSecAssert( output != NULL ) ;
339 fprintf( output, "== KEY SLOT\n" );
342 void
343 xmlSecNssKeySlotDebugXmlDump(
344 xmlSecNssKeySlotPtr keySlot ,
345 FILE* output
350 * Key Slot List
352 #ifdef __MINGW32__ // for runtime-pseudo-reloc
353 static struct _xmlSecPtrListKlass xmlSecNssKeySlotPtrListKlass = {
354 #else
355 static xmlSecPtrListKlass xmlSecNssKeySlotPtrListKlass = {
356 #endif
357 BAD_CAST "mechanism-list",
358 (xmlSecPtrDuplicateItemMethod)xmlSecNssKeySlotDuplicate,
359 (xmlSecPtrDestroyItemMethod)xmlSecNssKeySlotDestroy,
360 (xmlSecPtrDebugDumpItemMethod)xmlSecNssKeySlotDebugDump,
361 (xmlSecPtrDebugDumpItemMethod)xmlSecNssKeySlotDebugXmlDump,
364 xmlSecPtrListId
365 xmlSecNssKeySlotListGetKlass(void) {
366 return(&xmlSecNssKeySlotPtrListKlass);
371 * Global PKCS#11 crypto token repository -- Key slot list
373 static xmlSecPtrListPtr _xmlSecNssKeySlotList = NULL ;
375 PK11SlotInfo*
376 xmlSecNssSlotGet(
377 CK_MECHANISM_TYPE type
379 PK11SlotInfo* slot = NULL ;
380 xmlSecNssKeySlotPtr keySlot ;
381 xmlSecSize ksSize ;
382 xmlSecSize ksPos ;
383 char flag ;
385 if( _xmlSecNssKeySlotList == NULL ) {
386 slot = PK11_GetBestSlot( type , NULL ) ;
387 } else {
388 ksSize = xmlSecPtrListGetSize( _xmlSecNssKeySlotList ) ;
391 * Firstly, checking whether the mechanism is bound with a special slot.
392 * If no bound slot, we try to find the first eligible slot in the list.
394 for( flag = 0, ksPos = 0 ; ksPos < ksSize ; ksPos ++ ) {
395 keySlot = ( xmlSecNssKeySlotPtr )xmlSecPtrListGetItem( _xmlSecNssKeySlotList, ksPos ) ;
396 if( keySlot != NULL && xmlSecNssKeySlotBindMech( keySlot, type ) ) {
397 slot = xmlSecNssKeySlotGetSlot( keySlot ) ;
398 flag = 2 ;
399 } else if( flag == 0 && xmlSecNssKeySlotSupportMech( keySlot, type ) ) {
400 slot = xmlSecNssKeySlotGetSlot( keySlot ) ;
401 flag = 1 ;
404 if( flag == 2 )
405 break ;
407 if( slot != NULL )
408 slot = PK11_ReferenceSlot( slot ) ;
411 if( slot != NULL && PK11_NeedLogin( slot ) ) {
412 if( PK11_Authenticate( slot , PR_TRUE , NULL ) != SECSuccess ) {
413 xmlSecError( XMLSEC_ERRORS_HERE ,
414 NULL ,
415 NULL ,
416 XMLSEC_ERRORS_R_XMLSEC_FAILED ,
417 XMLSEC_ERRORS_NO_MESSAGE ) ;
418 PK11_FreeSlot( slot ) ;
419 return( NULL );
423 return slot ;
427 xmlSecNssSlotInitialize(
428 void
430 if( _xmlSecNssKeySlotList != NULL ) {
431 xmlSecPtrListDestroy( _xmlSecNssKeySlotList ) ;
432 _xmlSecNssKeySlotList = NULL ;
435 _xmlSecNssKeySlotList = xmlSecPtrListCreate( xmlSecNssKeySlotListId ) ;
436 if( _xmlSecNssKeySlotList == NULL ) {
437 xmlSecError( XMLSEC_ERRORS_HERE ,
438 NULL ,
439 NULL ,
440 XMLSEC_ERRORS_R_XMLSEC_FAILED ,
441 XMLSEC_ERRORS_NO_MESSAGE ) ;
442 return( -1 );
445 return(0);
448 void
449 xmlSecNssSlotShutdown(
450 void
452 if( _xmlSecNssKeySlotList != NULL ) {
453 xmlSecPtrListDestroy( _xmlSecNssKeySlotList ) ;
454 _xmlSecNssKeySlotList = NULL ;
459 xmlSecNssSlotAdopt(
460 PK11SlotInfo* slot,
461 CK_MECHANISM_TYPE type
463 xmlSecNssKeySlotPtr keySlot ;
464 xmlSecSize ksSize ;
465 xmlSecSize ksPos ;
466 char flag ;
468 xmlSecAssert2( _xmlSecNssKeySlotList != NULL, -1 ) ;
469 xmlSecAssert2( slot != NULL, -1 ) ;
471 ksSize = xmlSecPtrListGetSize( _xmlSecNssKeySlotList ) ;
474 * Firstly, checking whether the slot is in the repository already.
476 flag = 0 ;
477 for( ksPos = 0 ; ksPos < ksSize ; ksPos ++ ) {
478 keySlot = ( xmlSecNssKeySlotPtr )xmlSecPtrListGetItem( _xmlSecNssKeySlotList, ksPos ) ;
479 /* If find the slot in the list */
480 if( keySlot != NULL && xmlSecNssKeySlotGetSlot( keySlot ) == slot ) {
481 /* If mechnism type is valid, bind the slot with the mechanism */
482 if( type != CKM_INVALID_MECHANISM ) {
483 if( xmlSecNssKeySlotEnableMech( keySlot, type ) < 0 ) {
484 xmlSecError( XMLSEC_ERRORS_HERE ,
485 NULL ,
486 NULL ,
487 XMLSEC_ERRORS_R_XMLSEC_FAILED ,
488 XMLSEC_ERRORS_NO_MESSAGE ) ;
489 return(-1);
493 flag = 1 ;
497 /* If the slot do not in the list, add a new item to the list */
498 if( flag == 0 ) {
499 /* Create a new KeySlot */
500 keySlot = xmlSecNssKeySlotCreate() ;
501 if( keySlot == NULL ) {
502 xmlSecError( XMLSEC_ERRORS_HERE ,
503 NULL ,
504 NULL ,
505 XMLSEC_ERRORS_R_XMLSEC_FAILED ,
506 XMLSEC_ERRORS_NO_MESSAGE ) ;
507 return(-1);
510 /* Initialize the keySlot with a slot */
511 if( xmlSecNssKeySlotInitialize( keySlot, slot ) < 0 ) {
512 xmlSecError( XMLSEC_ERRORS_HERE ,
513 NULL ,
514 NULL ,
515 XMLSEC_ERRORS_R_XMLSEC_FAILED ,
516 XMLSEC_ERRORS_NO_MESSAGE ) ;
517 xmlSecNssKeySlotDestroy( keySlot ) ;
518 return(-1);
521 /* If mechnism type is valid, bind the slot with the mechanism */
522 if( type != CKM_INVALID_MECHANISM ) {
523 if( xmlSecNssKeySlotEnableMech( keySlot, type ) < 0 ) {
524 xmlSecError( XMLSEC_ERRORS_HERE ,
525 NULL ,
526 NULL ,
527 XMLSEC_ERRORS_R_XMLSEC_FAILED ,
528 XMLSEC_ERRORS_NO_MESSAGE ) ;
529 xmlSecNssKeySlotDestroy( keySlot ) ;
530 return(-1);
534 /* Add keySlot into the list */
535 if( xmlSecPtrListAdd( _xmlSecNssKeySlotList, keySlot ) < 0 ) {
536 xmlSecError( XMLSEC_ERRORS_HERE ,
537 NULL ,
538 NULL ,
539 XMLSEC_ERRORS_R_XMLSEC_FAILED ,
540 XMLSEC_ERRORS_NO_MESSAGE ) ;
541 xmlSecNssKeySlotDestroy( keySlot ) ;
542 return(-1);
546 return(0);