1 /* -*- mode: c; c-file-style:"stroustrup"; -*- */
2
3 /*
4 * Copyright (c) 2018 Mastercard
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include <config.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <ctype.h>
25 #include "pkcs11lib.h"
26
27 static CK_ATTRIBUTE_PTR new_attribute_for_bool(CK_ATTRIBUTE_TYPE argattrtype, CK_BBOOL argval);
28 static CK_ATTRIBUTE_PTR new_attribute_for_string(CK_ATTRIBUTE_TYPE argattrtype, char *arg);
29 static CK_ATTRIBUTE_PTR new_attribute_for_null_term_string(CK_ATTRIBUTE_TYPE argattrtype, char *arg);
30 static CK_ATTRIBUTE_PTR new_attribute_for_hex_string(CK_ATTRIBUTE_TYPE argattrtype, char *arg);
31
pkcs11_prompt(char * prompt,CK_BBOOL echo)32 char * pkcs11_prompt( char * prompt, CK_BBOOL echo )
33 {
34 char * buf = NULL;
35 char * res = NULL;
36 int n;
37
38 if ( ( buf = (char *) malloc( sizeof( char ) * MAXBUFSIZE ) ) == NULL )
39 {
40 fprintf( stderr, "Error: Unable to allocate system memory, exiting.\n" );
41 exit( RC_ERROR_MEMORY );
42 }
43
44 fprintf( stderr, "\n%s", prompt );
45 fflush( stdout );
46
47 if ( !echo ) {
48 pkcs11_ll_echo_off();
49 }
50
51 if ( ( res = fgets( buf, MAXBUFSIZE, stdin ) ) == NULL )
52 {
53 fprintf( stderr, "Error: Unable to read input, exiting.\n" );
54 exit( RC_ERROR_READ_INPUT );
55 }
56
57 n = strlen( res );
58
59 while ( buf[n - 1] != '\n' )
60 {
61 if ( ( buf = ( char * ) realloc( buf, n + MAXBUFSIZE ) ) == NULL )
62 {
63 fprintf( stderr, "Error: Unable to allocate system memory, exiting\n" );
64 exit( RC_ERROR_MEMORY );
65 }
66
67 if ( ( res = fgets( buf + n, MAXBUFSIZE, stdin ) ) == NULL )
68 {
69 fprintf( stderr, "Error: Unable to read input, exiting.\n" );
70 exit( RC_ERROR_READ_INPUT );
71 }
72
73 n += strlen( res );
74 }
75
76 buf[ n -1 ] = 0;
77
78 if ( !echo )
79 {
80 pkcs11_ll_echo_on();
81 }
82
83 printf("\n" );
84 return buf;
85 }
86
pkcs11_prompt_free_buffer(char * arg)87 void pkcs11_prompt_free_buffer(char *arg)
88 {
89 if(arg) free(arg);
90 }
91
92
pkcs11_pipe_password(char * passwordexec)93 char * pkcs11_pipe_password( char * passwordexec )
94 {
95 char * buf = NULL;
96
97 if(passwordexec!=NULL && strncmp(PASSWORD_EXEC, passwordexec, strlen(PASSWORD_EXEC))==0 ) {
98
99 size_t len=0, actual;
100 FILE * exec_pipe = popen (&passwordexec[strlen(PASSWORD_EXEC)], "r");
101
102 if(exec_pipe != NULL) {
103 actual = getline(&buf, &len, exec_pipe); /* password is allocated here */
104 pclose(exec_pipe); /* close the pipe */
105 if(buf[actual-1]=='\n') { buf[actual-1]=0x0; } /* clear line feed if found */
106 }
107
108
109 }
110
111 return buf;
112 }
113
114
115 /*--------------------------------------------------------------------*/
116
117
print_keyClass(CK_ULONG keyClass)118 char * print_keyClass( CK_ULONG keyClass )
119 {
120 char * rv = NULL;
121
122 switch ( keyClass )
123 {
124 case CKO_DATA :
125 rv = "CKO_DATA";
126 break;
127
128 case CKO_CERTIFICATE :
129 rv = "CKO_CERTIFICATE";
130 break;
131
132 case CKO_PUBLIC_KEY :
133 rv = "CKO_PUBLIC_KEY";
134 break;
135
136 case CKO_PRIVATE_KEY :
137 rv = "CKO_PRIVATE_KEY";
138 break;
139
140 case CKO_SECRET_KEY :
141 rv = "CKO_SECRET_KEY";
142 break;
143
144 case CKO_HW_FEATURE :
145 rv = "CKO_HW_FEATURE";
146 break;
147
148 case CKO_DOMAIN_PARAMETERS :
149 rv = "CKO_DOMAIN_PARAMETERS";
150 break;
151
152 case CKO_MECHANISM :
153 rv = "CKO_MECHANISM";
154 break;
155 }
156 return rv;
157 }
158
get_object_class(char * arg)159 CK_ULONG get_object_class(char *arg)
160 {
161 CK_ULONG class = 0;
162
163 if (strcasecmp(arg, "CKO_CERTIFICATE")==0) {
164 class = CKO_CERTIFICATE;
165 } else if (strcasecmp(arg, "CKO_PUBLIC_KEY")==0) {
166 class = CKO_PUBLIC_KEY;
167 } else if (strcasecmp(arg, "CKO_PRIVATE_KEY")==0) {
168 class = CKO_PRIVATE_KEY;
169 } else if (strcasecmp(arg, "CKO_SECRET_KEY")==0) {
170 class = CKO_SECRET_KEY;
171 }
172
173 return class;
174 }
175
176
get_attribute_type(char * arg)177 CK_ATTRIBUTE_TYPE get_attribute_type(char *arg)
178 {
179 CK_ATTRIBUTE_TYPE attrtype = 0xFFFFFFFF;
180
181 if (strcasecmp(arg, "CKA_ID")==0 || strcasecmp(arg, "ID")==0) {
182 attrtype = CKA_ID;
183 } else if (strcasecmp(arg, "CKA_LABEL")==0 || strcasecmp(arg, "LABEL")==0) {
184 attrtype = CKA_LABEL;
185 } else if (strcasecmp(arg, "CKA_WRAP")==0 || strcasecmp(arg, "WRAP")==0) {
186 attrtype = CKA_WRAP;
187 } else if (strcasecmp(arg, "CKA_UNWRAP")==0 || strcasecmp(arg, "UNWRAP")==0) {
188 attrtype = CKA_UNWRAP;
189 } else if (strcasecmp(arg, "CKA_ENCRYPT")==0 || strcasecmp(arg, "ENCRYPT")==0) {
190 attrtype = CKA_ENCRYPT;
191 } else if (strcasecmp(arg, "CKA_DECRYPT")==0 || strcasecmp(arg, "DECRYPT")==0) {
192 attrtype = CKA_DECRYPT;
193 } else if (strcasecmp(arg, "CKA_SIGN")==0 || strcasecmp(arg, "SIGN")==0) {
194 attrtype = CKA_SIGN;
195 } else if (strcasecmp(arg, "CKA_VERIFY")==0 || strcasecmp(arg, "VERIFY")==0) {
196 attrtype = CKA_VERIFY;
197 } else if (strcasecmp(arg, "CKA_SIGN_RECOVER")==0 || strcasecmp(arg, "SIGN_RECOVER")==0) {
198 attrtype = CKA_SIGN_RECOVER;
199 } else if (strcasecmp(arg, "CKA_VERIFY_RECOVER")==0 || strcasecmp(arg, "VERIFY_RECOVER")==0) {
200 attrtype = CKA_VERIFY_RECOVER;
201 } else if (strcasecmp(arg, "CKA_DERIVE")==0 || strcasecmp(arg, "DERIVE")==0) {
202 attrtype = CKA_DERIVE;
203 } else if (strcasecmp(arg, "CKA_TRUSTED")==0 || strcasecmp(arg, "TRUSTED")==0) {
204 attrtype = CKA_TRUSTED;
205 } else if (strcasecmp(arg, "CKA_WRAP_WITH_TRUSTED")==0 || strcasecmp(arg, "WRAP_WITH_TRUSTED")==0) {
206 attrtype = CKA_WRAP_WITH_TRUSTED;
207 } else if (strcasecmp(arg, "CKA_MODIFIABLE")==0 || strcasecmp(arg, "MODIFIABLE")==0) {
208 attrtype = CKA_MODIFIABLE;
209 } else if (strcasecmp(arg, "CKA_EXTRACTABLE")==0 || strcasecmp(arg, "EXTRACTABLE")==0) {
210 attrtype = CKA_EXTRACTABLE;
211 } else if (strcasecmp(arg, "CKA_SENSITIVE")==0 || strcasecmp(arg, "SENSITIVE")==0) {
212 attrtype = CKA_SENSITIVE;
213 /* EC attributes */
214 } else if (strcasecmp(arg, "CKA_EC_PARAMS")==0 || strcasecmp(arg, "EC_PARAMS")==0) {
215 attrtype = CKA_EC_PARAMS;
216 /* NSS attributes */
217 } else if (strcasecmp(arg, "CKA_TRUST_SERVER_AUTH")==0 || strcasecmp(arg, "TRUST_SERVER_AUTH")==0) {
218 attrtype = CKA_TRUST_SERVER_AUTH;
219 } else if (strcasecmp(arg, "CKA_TRUST_CLIENT_AUTH")==0 || strcasecmp(arg, "TRUST_CLIENT_AUTH")==0) {
220 attrtype = CKA_TRUST_CLIENT_AUTH;
221 } else if (strcasecmp(arg, "CKA_TRUST_CODE_SIGNING")==0 || strcasecmp(arg, "TRUST_CODE_SIGNING")==0) {
222 attrtype = CKA_TRUST_CODE_SIGNING;
223 } else if (strcasecmp(arg, "CKA_TRUST_EMAIL_PROTECTION")==0 || strcasecmp(arg, "TRUST_EMAIL_PROTECTION")==0) {
224 attrtype = CKA_TRUST_EMAIL_PROTECTION;
225 }
226
227 return attrtype;
228 }
229
230
new_attribute_for_bool(CK_ATTRIBUTE_TYPE argattrtype,CK_BBOOL argval)231 static CK_ATTRIBUTE_PTR new_attribute_for_bool(CK_ATTRIBUTE_TYPE argattrtype, CK_BBOOL argval)
232 {
233 CK_ATTRIBUTE_PTR attr = NULL;
234
235 attr = malloc ( sizeof ( CK_ATTRIBUTE ) );
236
237 if ( attr != NULL ) {
238 CK_BBOOL* boolptr = malloc ( sizeof ( CK_BBOOL ) );
239
240 if ( boolptr != NULL ) {
241 *boolptr = argval; /* copy the value we received */
242 attr->type = argattrtype;
243 attr->pValue = boolptr;
244 attr->ulValueLen = sizeof( CK_BBOOL );
245 } else {
246 fprintf( stderr, "Error: lack of memory\n");
247 free( attr);
248 }
249 } else {
250 fprintf( stderr, "Error: lack of memory\n");
251 }
252
253 return attr;
254 }
255
new_attribute_for_string(CK_ATTRIBUTE_TYPE argattrtype,char * arg)256 CK_ATTRIBUTE_PTR new_attribute_for_string(CK_ATTRIBUTE_TYPE argattrtype, char *arg)
257 {
258 if(strchr(arg, '{' ) && strrchr(arg, '}')) {
259 /* we have an hex string */
260 return new_attribute_for_hex_string( argattrtype, arg);
261 } else {
262 return new_attribute_for_null_term_string( argattrtype, arg);
263 }
264 }
265
new_attribute_for_null_term_string(CK_ATTRIBUTE_TYPE argattrtype,char * arg)266 CK_ATTRIBUTE_PTR new_attribute_for_null_term_string(CK_ATTRIBUTE_TYPE argattrtype, char *arg)
267 {
268 CK_ATTRIBUTE_PTR attr = NULL;
269
270 attr = calloc ( 1, sizeof ( CK_ATTRIBUTE ) );
271
272 if ( attr != NULL ) {
273 char *strptr = calloc ( strlen(arg)+1, sizeof (char) );
274
275 if ( strptr != NULL ) {
276 strcpy(strptr, arg);
277
278 attr->type = argattrtype;
279 attr->pValue = strptr;
280 attr->ulValueLen = strlen(arg); /* we stop at character's end */
281 } else {
282 fprintf( stderr, "Error: lack of memory\n");
283 free(attr);
284 }
285 } else {
286 fprintf( stderr, "Error: lack of memory\n");
287 }
288
289 return attr;
290 }
291
new_attribute_for_hex_string(CK_ATTRIBUTE_TYPE argattrtype,char * arg)292 CK_ATTRIBUTE_PTR new_attribute_for_hex_string(CK_ATTRIBUTE_TYPE argattrtype, char *arg)
293 {
294 CK_ATTRIBUTE_PTR attr = NULL;
295
296 attr = calloc ( 1, sizeof ( CK_ATTRIBUTE ) );
297
298 if ( attr != NULL ) {
299 size_t outsize=0;
300 char *hexstr = hex2bin_new( arg, strlen(arg), &outsize);
301
302 if ( hexstr != NULL ) {
303
304 char *dupstr = malloc(outsize);
305
306 if ( dupstr != NULL ) {
307 memcpy(dupstr,hexstr,outsize);
308 /* duplicate buffer */
309 /* and assign it */
310 attr->type = argattrtype;
311 attr->pValue = dupstr;
312 attr->ulValueLen = outsize;
313 } else {
314 fprintf( stderr, "Error: lack of memory\n");
315 free(attr);
316 }
317 hex2bin_free(hexstr); /* free buf in any case */
318
319 } else {
320 fprintf( stderr, "Error: lack of memory\n");
321 free(attr);
322 }
323 } else {
324 fprintf( stderr, "Error: lack of memory\n");
325 }
326
327 return attr;
328 }
329
330
hex2bin_new(char * label,size_t size,size_t * outsize)331 char * hex2bin_new(char *label, size_t size, size_t *outsize)
332 {
333
334 char *pos, *initpos;
335 char *tmpbuf=NULL, *tmpbuf_s=NULL;
336 char *target;
337 size_t len;
338 size_t ws_cnt, i;
339
340
341 /* since there can be decoration characters in the input string, */
342 /* and since the resulting hex chars can be an odd number */
343 /* we first pass to count decoration chars, */
344 /* then we allocate buffer and prepend with a '0' if odd, */
345 /* then we copy significant characters. */
346
347 /* #1: count the number of decoration chars in the string */
348 /* see regular expression definition in calling function */
349 /* for the definition of a decoration character */
350
351 for (i=0, ws_cnt=0; i<size; i++) {
352 if( !isxdigit(label[i]) ) {
353 /* TODO: check if we indeed have a decorator character */
354 /* to detect hex strings containing other alphabet letters */
355 ws_cnt++;
356 }
357 }
358
359 /* #2: allocate tmpbuf with right size and prepend with a leading '0' if needed */
360 len = (size-ws_cnt)+ ((size-ws_cnt)%2);
361 tmpbuf = calloc(sizeof(char), len+1);
362
363 tmpbuf_s=tmpbuf;
364
365 if((size-ws_cnt)%2) { /* odd length, we need to prepend with a '0' */
366 *tmpbuf_s++='0';
367 }
368
369 /* #3: copy characters, but skip whitespaces */
370 for (i=0; i<size; i++) {
371 if( isxdigit(label[i]) ) {
372 *tmpbuf_s++=label[i];
373 }
374 }
375
376 /* #4: output buffer determination */
377 *outsize = len >> 1;
378 target = malloc( *outsize );
379
380 /* #5: scan resulting set and conversion */
381 for( initpos = pos = tmpbuf; *pos && (pos-initpos < len); ++pos)
382 {
383 if( !((pos-initpos)&1) ) {
384 sscanf(pos,"%2hhx", &target[(pos-initpos)>>1]);
385 }
386 }
387
388 if(tmpbuf) {
389 free(tmpbuf);
390 }
391
392 return target;
393
394 }
395
hex2bin_free(char * ptr)396 void hex2bin_free(char *ptr)
397 {
398 if(ptr) {
399 free(ptr);
400 }
401 }
402
get_attribute_for_type_and_value(CK_ATTRIBUTE_TYPE argattrtype,char * arg)403 CK_ATTRIBUTE_PTR get_attribute_for_type_and_value(CK_ATTRIBUTE_TYPE argattrtype, char *arg )
404 {
405 CK_ATTRIBUTE_PTR attr = NULL;
406
407 switch(argattrtype) {
408 case CKA_WRAP:
409 case CKA_UNWRAP:
410 case CKA_ENCRYPT:
411 case CKA_DECRYPT:
412 case CKA_SIGN:
413 case CKA_VERIFY:
414 case CKA_SIGN_RECOVER:
415 case CKA_VERIFY_RECOVER:
416 case CKA_DERIVE:
417 case CKA_TRUSTED:
418 case CKA_WRAP_WITH_TRUSTED:
419 case CKA_MODIFIABLE:
420 case CKA_EXTRACTABLE:
421 case CKA_SENSITIVE:
422 /* NSS-specific */
423 case CKA_TRUST_SERVER_AUTH:
424 case CKA_TRUST_CLIENT_AUTH:
425 case CKA_TRUST_CODE_SIGNING:
426 case CKA_TRUST_EMAIL_PROTECTION:
427 {
428 CK_BBOOL val;
429
430 if ( strcasecmp(arg, "true")==0 || strcasecmp(arg, "yes")==0 || strcasecmp(arg, "1")==0 ) {
431 val = CK_TRUE;
432 attr = new_attribute_for_bool( argattrtype, val);
433 } else if ( strcasecmp(arg, "false")==0 || strcasecmp(arg, "no")==0 || strcasecmp(arg,"0")==0) {
434 val = CK_FALSE;
435 attr = new_attribute_for_bool( argattrtype, val);
436 } else {
437 fprintf(stderr, "Error: value for boolean attribute must be either TRUE or FALSE\n");
438 }
439 }
440 break;
441
442 case CKA_ID:
443 case CKA_LABEL:
444 attr = new_attribute_for_string(argattrtype, arg);
445 break;
446
447 default:
448 fprintf( stderr, "please specify an attribute type before giving a value");
449 }
450
451 return attr;
452 }
453
454
print_keyType(CK_ULONG keyType)455 char * print_keyType( CK_ULONG keyType )
456 {
457 switch( keyType )
458 {
459 case CKK_AES :
460 return "CKK_AES";
461 case CKK_DES :
462 return "CKK_DES";
463 case CKK_DES3 :
464 return "CKK_DES3";
465 case CKK_RSA :
466 return "CKK_RSA";
467 case CKK_GENERIC_SECRET :
468 return "CKK_GENERIC_SECRET";
469 #ifdef CKK_SHA_1_HMAC
470 case CKK_SHA_1_HMAC :
471 return "CKK_SHA_1_HMAC";
472 #endif
473 default :
474 return "CKK_VENDOR_DEFINED";
475 }
476 }
477
478
479
get_attributes_from_argv(CK_ATTRIBUTE * attrs[],int pos,int argc,char ** argv)480 int get_attributes_from_argv( CK_ATTRIBUTE *attrs[] , int pos, int argc, char **argv)
481 {
482
483 int i;
484 char *cpy = NULL;
485 int rv = 0;
486 int cnt = 0;
487
488 for (i=pos; i<argc; ++i) {
489 char *a, *v;
490 CK_ATTRIBUTE_TYPE typ;
491 CK_ATTRIBUTE_PTR val;
492
493 if((cpy = malloc( strlen(argv[i]) + 1 )) == NULL ) {
494 fprintf(stderr,"Error: can't allocate memory\n");
495 goto err;
496 }
497 strcpy(cpy, argv[i]);
498
499 a = strtok(cpy, ":=");
500 if(a==NULL) {
501 fprintf(stderr, "Error: argument ""%s"" contains no separator ( : or = )\n", argv[i]);
502 goto err;
503 }
504
505 typ = get_attribute_type(a);
506 if(typ==0xFFFFFFFF) {
507 fprintf(stderr, "Error: unknown attribute type ""%s""\n", a);
508 goto err;
509
510 }
511
512 v = strtok(NULL, ":=");
513
514 if(v==NULL) {
515 fprintf(stderr, "Error: argument ""%s"" has no value\n", argv[i]);
516 goto err;
517 }
518 val = get_attribute_for_type_and_value(typ, v);
519
520 if(val==NULL) {
521 fprintf(stderr, "Error: wrong attribute value ""%s""\n", v);
522 goto err;
523 }
524
525 release_attribute(val); val=NULL;
526 free(cpy); cpy=NULL;
527
528 cnt++;
529 }
530
531
532 /* now allocate array of attributes */
533 if(cnt==0) {
534 fprintf(stderr, "Error: no attribute-value pair argument specified\n");
535 goto err;
536 }
537
538 *attrs = calloc( cnt, sizeof(CK_ATTRIBUTE) ); /* allocate from heap */
539
540 if(*attrs == NULL) {
541 fprintf(stderr, "Error: can't allocate memory\n");
542 goto err;
543 }
544
545
546 for(i=pos; i<argc; i++) {
547 char *a, *v;
548 CK_ATTRIBUTE_PTR item;
549
550 a = strtok(argv[i], ":=");
551 v = strtok(NULL, ":=");
552
553 item = get_attribute_for_type_and_value( get_attribute_type(a), v );
554 memcpy( &((*attrs)[i-pos]), item, sizeof( CK_ATTRIBUTE ) );
555 item->pValue=NULL; /* caution! we have moved pValue to the array */
556 /* we must clear it from the initial structure */
557 release_attribute(item);
558 }
559
560 rv = cnt;
561
562 err:
563 if(cpy) { free(cpy); cpy = NULL; }
564
565 return rv;
566 }
567
release_attribute(CK_ATTRIBUTE_PTR arg)568 void release_attribute( CK_ATTRIBUTE_PTR arg)
569 {
570 if(arg) {
571 if (arg->pValue) {
572 free(arg->pValue);
573 }
574 free(arg);
575 }
576 }
577
578
release_attributes(CK_ATTRIBUTE attrs[],size_t cnt)579 void release_attributes(CK_ATTRIBUTE attrs[], size_t cnt)
580 {
581 if(attrs) {
582 int i;
583
584 for(i=0; i<cnt; i++) {
585 CK_ATTRIBUTE_PTR item = &attrs[i];
586 if (item->pValue) {
587 free(item->pValue);
588 }
589 }
590
591 free(attrs); /* free table, eventually */
592 }
593 }
594
prompt_for_hex(char * message,char * prompt,char * target,int len)595 func_rc prompt_for_hex(char *message, char *prompt, char *target, int len)
596 {
597 func_rc rc = RC_OK;
598
599 char *spacer = " ";
600 char *helper1 = "00 11 22 33 ";
601 char *helper2 = "1122334455667788990011223344556677889900112233445566778899001122";
602
603 char *buf=NULL, *pos;
604 size_t buf_len=0;
605
606 if(message && prompt && target && len>0) {
607
608 int prompt_len = strlen(prompt);
609
610 printf("%s\n\n%.*s%.*s\n%.*s%.*s\n%s ",
611 message,
612 prompt_len+1, spacer, len<<1, helper1,
613 prompt_len+1, spacer, len<<1, helper2,
614 prompt);
615
616 fflush(stdout);
617
618 getline(&buf, &buf_len, stdin); /* buffer is allocated */
619
620 pos = buf;
621 while( *pos )
622 {
623 unsigned int x;
624 if( !((pos-buf)&1) ) {
625 if (((pos-buf)>>1) == len ) break;
626 /* because sscanf returns the value as an unsigned int, */
627 /* we must pass through type casting to avoid memory/stack overflow */
628 sscanf(pos,"%02x", &x);
629 target[(pos-buf)>>1]= (unsigned char)x;
630 }
631 ++pos;
632 }
633
634 if(buf) free(buf);
635 }
636
637 return rc;
638 }
639
640
641
642
643
644 #define MAXOF(x,y) ((x)>(y)) ? (x) : (y)
645 #define MINOF(x,y) ((x)<(y)) ? (x) : (y)
646
647 #define UNLABELLED_OBJECT "???unlabelled object???"
648
label_or_id(CK_ATTRIBUTE_PTR label,CK_ATTRIBUTE_PTR id,char * buffer,int buffer_len)649 char * label_or_id(CK_ATTRIBUTE_PTR label, CK_ATTRIBUTE_PTR id, char *buffer, int buffer_len)
650 {
651 if(label && label->ulValueLen>0) { /* we have a label, let's use it */
652 /* label is NEVER null terminated */
653 /* we cannot use strncpy */
654 memcpy( buffer, label->pValue, MINOF(buffer_len-1,label->ulValueLen));
655 buffer[ MINOF(buffer_len-1,label->ulValueLen) ] = 0; /* terminate the string */
656 } else if(id && id->ulValueLen>0) { /* we have no label apparently */
657 char *hexidptr = buffer;
658 CK_BYTE_PTR idptr = id->pValue;
659 CK_ULONG idcnt=0;
660
661 *hexidptr++='i';
662 *hexidptr++='d';
663 *hexidptr++='/';
664 *hexidptr++='{';
665 idptr = (CK_BYTE_PTR)id->pValue;
666
667 while(hexidptr-buffer<(buffer_len - 2) && idcnt<id->ulValueLen) {
668 sprintf(hexidptr,"%2.2x", idptr[idcnt++]);
669 hexidptr+=2;
670 }
671 *hexidptr++='}';
672 *hexidptr='\0';
673 } else { /* no id or label */
674 strncpy(buffer, UNLABELLED_OBJECT , MINOF(buffer_len-1, strlen(UNLABELLED_OBJECT)));
675 buffer[ MINOF(buffer_len-1, strlen(UNLABELLED_OBJECT)) ] = 0; /* terminate string */
676 }
677
678 return buffer;
679 }
680
681
682 /*
683 *--------------------------------------------------------------------------------
684 * $Log$
685 *--------------------------------------------------------------------------------
686 */
687