61
61
62
62
#if defined(ENABLE_PKCS11H_TOKEN ) || defined(ENABLE_PKCS11H_CERTIFICATE )
63
63
64
+ #define URI_SCHEME "pkcs11:"
65
+
66
+ #define token_field_ofs (field ) ((unsigned long)&(((struct pkcs11h_token_id_s *)0)->field))
67
+ #define token_field_size (field ) sizeof((((struct pkcs11h_token_id_s *)0)->field))
68
+ #define token_field (name , field ) { name "=", sizeof(name), \
69
+ token_field_ofs(field), token_field_size(field) }
70
+
71
+ static struct {
72
+ const char const * name ;
73
+ size_t namelen ;
74
+ unsigned long field_ofs ;
75
+ size_t field_size ;
76
+ } __token_fields [] = {
77
+ token_field ("model" , model ),
78
+ token_field ("token" , label ),
79
+ token_field ("manufacturer" , manufacturerID ),
80
+ token_field ("serial" , serialNumber ),
81
+ { NULL },
82
+ };
83
+
64
84
CK_RV
65
85
pkcs11h_token_serializeTokenId (
66
86
OUT char * const sz ,
@@ -150,9 +170,147 @@ pkcs11h_token_serializeTokenId (
150
170
return rv ;
151
171
}
152
172
173
+ static
153
174
CK_RV
154
- pkcs11h_token_deserializeTokenId (
155
- OUT pkcs11h_token_id_t * p_token_id ,
175
+ __parse_token_uri_attr (
176
+ const char * uri ,
177
+ size_t urilen ,
178
+ char * tokstr ,
179
+ size_t toklen ,
180
+ size_t * parsed_len
181
+ ) {
182
+ size_t orig_toklen = toklen ;
183
+ CK_RV rv = CKR_OK ;
184
+
185
+ while (urilen && toklen > 1 ) {
186
+ if (* uri == '%' ) {
187
+ size_t size = 1 ;
188
+
189
+ if (urilen < 3 ) {
190
+ rv = CKR_ATTRIBUTE_VALUE_INVALID ;
191
+ goto done ;
192
+ }
193
+
194
+ rv = _pkcs11h_util_hexToBinary ((unsigned char * )tokstr ,
195
+ uri + 1 , & size );
196
+ if (rv != CKR_OK ) {
197
+ goto done ;
198
+ }
199
+
200
+ uri += 2 ;
201
+ urilen -= 2 ;
202
+ } else {
203
+ * tokstr = * uri ;
204
+ }
205
+ tokstr ++ ;
206
+ uri ++ ;
207
+ toklen -- ;
208
+ urilen -- ;
209
+ tokstr [1 ] = 0 ;
210
+ }
211
+
212
+ if (urilen ) {
213
+ rv = CKR_ATTRIBUTE_VALUE_INVALID ;
214
+ } else if (parsed_len ) {
215
+ * parsed_len = orig_toklen - toklen ;
216
+ }
217
+
218
+ done :
219
+ return rv ;
220
+ }
221
+
222
+ static
223
+ CK_RV
224
+ __parse_pkcs11_uri (
225
+ OUT pkcs11h_token_id_t token_id ,
226
+ OUT pkcs11h_certificate_id_t certificate_id ,
227
+ IN const char * const sz
228
+ ) {
229
+ const char * end , * p ;
230
+ CK_RV rv = CKR_OK ;
231
+
232
+ _PKCS11H_ASSERT (token_id != NULL );
233
+ _PKCS11H_ASSERT (sz != NULL );
234
+
235
+ if (strncmp (sz , URI_SCHEME , strlen (URI_SCHEME )))
236
+ return CKR_ATTRIBUTE_VALUE_INVALID ;
237
+
238
+ end = sz + strlen (URI_SCHEME ) - 1 ;
239
+ while (rv == CKR_OK && end [0 ] && end [1 ]) {
240
+ int i ;
241
+
242
+ p = end + 1 ;
243
+ end = strchr (p , ';' );
244
+ if (!end )
245
+ end = p + strlen (p );
246
+
247
+ for (i = 0 ; __token_fields [i ].name ; i ++ ) {
248
+ /* Parse the token=, label=, manufacturer= and serial= fields */
249
+ if (!strncmp (p , __token_fields [i ].name , __token_fields [i ].namelen )) {
250
+ char * field = ((char * )token_id ) + __token_fields [i ].field_ofs ;
251
+
252
+ p += __token_fields [i ].namelen ;
253
+ rv = __parse_token_uri_attr (p , end - p , field ,
254
+ __token_fields [i ].field_size ,
255
+ NULL );
256
+ if (rv != CKR_OK ) {
257
+ goto cleanup ;
258
+ }
259
+
260
+ goto matched ;
261
+ }
262
+ }
263
+ if (certificate_id && !strncmp (p , "id=" , 3 )) {
264
+ p += 3 ;
265
+
266
+ rv = _pkcs11h_mem_malloc ((void * )& certificate_id -> attrCKA_ID ,
267
+ end - p + 1 );
268
+ if (rv != CKR_OK ) {
269
+ goto cleanup ;
270
+ }
271
+
272
+ rv = __parse_token_uri_attr (p , end - p ,
273
+ (char * )certificate_id -> attrCKA_ID ,
274
+ end - p + 1 ,
275
+ & certificate_id -> attrCKA_ID_size );
276
+ if (rv != CKR_OK ) {
277
+ goto cleanup ;
278
+ }
279
+
280
+ goto matched ;
281
+ }
282
+
283
+ /* We don't parse object= because the match code doesn't support
284
+ matching by label. */
285
+
286
+ /* Failed to parse PKCS#11 URI element. */
287
+ return CKR_ATTRIBUTE_VALUE_INVALID ;
288
+
289
+ matched :
290
+ ;
291
+ }
292
+ cleanup :
293
+ /* The matching code doesn't support support partial matches; it needs
294
+ * *all* of manufacturer, model, serial and label attributes to be
295
+ * defined. So reject partial URIs early instead of letting it do the
296
+ * wrong thing. We can maybe improve this later. */
297
+ if (!token_id -> model [0 ] || !token_id -> label [0 ] ||
298
+ !token_id -> manufacturerID [0 ] || !token_id -> serialNumber [0 ]) {
299
+ return CKR_ATTRIBUTE_VALUE_INVALID ;
300
+ }
301
+
302
+ /* For a certificate ID we need CKA_ID */
303
+ if (certificate_id && !certificate_id -> attrCKA_ID_size ) {
304
+ return CKR_ATTRIBUTE_VALUE_INVALID ;
305
+ }
306
+
307
+ return rv ;
308
+ }
309
+
310
+ static
311
+ CK_RV
312
+ __pkcs11h_token_legacy_deserializeTokenId (
313
+ OUT pkcs11h_token_id_t token_id ,
156
314
IN const char * const sz
157
315
) {
158
316
#define __PKCS11H_TARGETS_NUMBER 4
@@ -161,24 +319,11 @@ pkcs11h_token_deserializeTokenId (
161
319
size_t s ;
162
320
} targets [__PKCS11H_TARGETS_NUMBER ];
163
321
164
- pkcs11h_token_id_t token_id = NULL ;
165
322
char * p1 = NULL ;
166
323
char * _sz = NULL ;
167
324
int e ;
168
325
CK_RV rv = CKR_FUNCTION_FAILED ;
169
326
170
- _PKCS11H_ASSERT (p_token_id != NULL );
171
- _PKCS11H_ASSERT (sz != NULL );
172
-
173
- _PKCS11H_DEBUG (
174
- PKCS11H_LOG_DEBUG2 ,
175
- "PKCS#11: pkcs11h_token_deserializeTokenId entry p_token_id=%p, sz='%s'" ,
176
- (void * )p_token_id ,
177
- sz
178
- );
179
-
180
- * p_token_id = NULL ;
181
-
182
327
if (
183
328
(rv = _pkcs11h_mem_strdup (
184
329
(void * )& _sz ,
@@ -190,10 +335,6 @@ pkcs11h_token_deserializeTokenId (
190
335
191
336
p1 = _sz ;
192
337
193
- if ((rv = _pkcs11h_token_newTokenId (& token_id )) != CKR_OK ) {
194
- goto cleanup ;
195
- }
196
-
197
338
targets [0 ].p = token_id -> manufacturerID ;
198
339
targets [0 ].s = sizeof (token_id -> manufacturerID );
199
340
targets [1 ].p = token_id -> model ;
@@ -252,6 +393,51 @@ pkcs11h_token_deserializeTokenId (
252
393
p1 = p2 + 1 ;
253
394
}
254
395
396
+ rv = CKR_OK ;
397
+
398
+ cleanup :
399
+
400
+ if (_sz != NULL ) {
401
+ _pkcs11h_mem_free ((void * )& _sz );
402
+ }
403
+
404
+ return rv ;
405
+ #undef __PKCS11H_TARGETS_NUMBER
406
+ }
407
+
408
+ CK_RV
409
+ pkcs11h_token_deserializeTokenId (
410
+ OUT pkcs11h_token_id_t * p_token_id ,
411
+ IN const char * const sz
412
+ ) {
413
+ pkcs11h_token_id_t token_id = NULL ;
414
+ CK_RV rv = CKR_FUNCTION_FAILED ;
415
+
416
+ _PKCS11H_ASSERT (p_token_id != NULL );
417
+ _PKCS11H_ASSERT (sz != NULL );
418
+
419
+ _PKCS11H_DEBUG (
420
+ PKCS11H_LOG_DEBUG2 ,
421
+ "PKCS#11: pkcs11h_token_deserializeTokenId entry p_token_id=%p, sz='%s'" ,
422
+ (void * )p_token_id ,
423
+ sz
424
+ );
425
+
426
+ * p_token_id = NULL ;
427
+
428
+ if ((rv = _pkcs11h_token_newTokenId (& token_id )) != CKR_OK ) {
429
+ goto cleanup ;
430
+ }
431
+
432
+ if (!strncmp (sz , URI_SCHEME , strlen (URI_SCHEME ))) {
433
+ rv = __parse_pkcs11_uri (token_id , NULL , sz );
434
+ } else {
435
+ rv = __pkcs11h_token_legacy_deserializeTokenId (token_id , sz );
436
+ }
437
+ if (rv != CKR_OK ) {
438
+ goto cleanup ;
439
+ }
440
+
255
441
strncpy (
256
442
token_id -> display ,
257
443
token_id -> label ,
@@ -264,11 +450,6 @@ pkcs11h_token_deserializeTokenId (
264
450
rv = CKR_OK ;
265
451
266
452
cleanup :
267
-
268
- if (_sz != NULL ) {
269
- _pkcs11h_mem_free ((void * )& _sz );
270
- }
271
-
272
453
if (token_id != NULL ) {
273
454
pkcs11h_token_freeTokenId (token_id );
274
455
}
@@ -281,7 +462,6 @@ pkcs11h_token_deserializeTokenId (
281
462
);
282
463
283
464
return rv ;
284
- #undef __PKCS11H_TARGETS_NUMBER
285
465
}
286
466
287
467
#endif /* ENABLE_PKCS11H_TOKEN || ENABLE_PKCS11H_CERTIFICATE */
@@ -360,29 +540,17 @@ pkcs11h_certificate_serializeCertificateId (
360
540
return rv ;
361
541
}
362
542
543
+ static
363
544
CK_RV
364
- pkcs11h_certificate_deserializeCertificateId (
365
- OUT pkcs11h_certificate_id_t * const p_certificate_id ,
545
+ __pkcs11h_certificate_legacy_deserializeCertificateId (
546
+ OUT pkcs11h_certificate_id_t certificate_id ,
366
547
IN const char * const sz
367
548
) {
368
- pkcs11h_certificate_id_t certificate_id = NULL ;
369
549
CK_RV rv = CKR_FUNCTION_FAILED ;
370
550
char * p = NULL ;
371
551
char * _sz = NULL ;
372
552
size_t id_hex_len ;
373
553
374
- _PKCS11H_ASSERT (p_certificate_id != NULL );
375
- _PKCS11H_ASSERT (sz != NULL );
376
-
377
- * p_certificate_id = NULL ;
378
-
379
- _PKCS11H_DEBUG (
380
- PKCS11H_LOG_DEBUG2 ,
381
- "PKCS#11: pkcs11h_certificate_deserializeCertificateId entry p_certificate_id=%p, sz='%s'" ,
382
- (void * )p_certificate_id ,
383
- sz
384
- );
385
-
386
554
if (
387
555
(rv = _pkcs11h_mem_strdup (
388
556
(void * )& _sz ,
@@ -394,10 +562,6 @@ pkcs11h_certificate_deserializeCertificateId (
394
562
395
563
p = _sz ;
396
564
397
- if ((rv = _pkcs11h_certificate_newCertificateId (& certificate_id )) != CKR_OK ) {
398
- goto cleanup ;
399
- }
400
-
401
565
if ((p = strrchr (_sz , '/' )) == NULL ) {
402
566
rv = CKR_ATTRIBUTE_VALUE_INVALID ;
403
567
goto cleanup ;
@@ -436,21 +600,64 @@ pkcs11h_certificate_deserializeCertificateId (
436
600
goto cleanup ;
437
601
}
438
602
603
+ rv = CKR_OK ;
604
+
605
+ cleanup :
606
+
607
+ if (_sz != NULL ) {
608
+ _pkcs11h_mem_free ((void * )& _sz );
609
+ }
610
+
611
+ return rv ;
612
+
613
+ }
614
+
615
+ CK_RV
616
+ pkcs11h_certificate_deserializeCertificateId (
617
+ OUT pkcs11h_certificate_id_t * const p_certificate_id ,
618
+ IN const char * const sz
619
+ ) {
620
+ pkcs11h_certificate_id_t certificate_id = NULL ;
621
+ CK_RV rv = CKR_FUNCTION_FAILED ;
622
+
623
+ _PKCS11H_ASSERT (p_certificate_id != NULL );
624
+ _PKCS11H_ASSERT (sz != NULL );
625
+
626
+ * p_certificate_id = NULL ;
627
+
628
+ _PKCS11H_DEBUG (
629
+ PKCS11H_LOG_DEBUG2 ,
630
+ "PKCS#11: pkcs11h_certificate_deserializeCertificateId entry p_certificate_id=%p, sz='%s'" ,
631
+ (void * )p_certificate_id ,
632
+ sz
633
+ );
634
+
635
+ if ((rv = _pkcs11h_certificate_newCertificateId (& certificate_id )) != CKR_OK ) {
636
+ goto cleanup ;
637
+ }
638
+ if ((rv = _pkcs11h_token_newTokenId (& certificate_id -> token_id )) != CKR_OK ) {
639
+ goto cleanup ;
640
+ }
641
+
642
+ if (!strncmp (sz , URI_SCHEME , strlen (URI_SCHEME ))) {
643
+ rv = __parse_pkcs11_uri (certificate_id -> token_id , certificate_id , sz );
644
+ } else {
645
+ rv = __pkcs11h_certificate_legacy_deserializeCertificateId (certificate_id , sz );
646
+ }
647
+ if (rv != CKR_OK ) {
648
+ goto cleanup ;
649
+ }
650
+
439
651
* p_certificate_id = certificate_id ;
440
652
certificate_id = NULL ;
441
653
rv = CKR_OK ;
442
654
443
655
cleanup :
444
-
445
656
if (certificate_id != NULL ) {
446
657
pkcs11h_certificate_freeCertificateId (certificate_id );
447
658
certificate_id = NULL ;
448
659
}
449
660
450
- if (_sz != NULL ) {
451
- _pkcs11h_mem_free ((void * )& _sz );
452
- }
453
-
454
661
_PKCS11H_DEBUG (
455
662
PKCS11H_LOG_DEBUG2 ,
456
663
"PKCS#11: pkcs11h_certificate_deserializeCertificateId return rv=%lu-'%s'" ,
0 commit comments