1 /*
2 * Copyright (c) 2005-2018 Alon Bar-Lev <alon.barlev@gmail.com>
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, or the BSD license.
7 *
8 * GNU General Public License (GPL) Version 2
9 * ===========================================
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING.GPL included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 *
24 * BSD License
25 * ============
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions are met:
28 *
29 * o Redistributions of source code must retain the above copyright notice,
30 * this list of conditions and the following disclaimer.
31 * o Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 * o Neither the name of the Alon Bar-Lev nor the names of its
35 * contributors may be used to endorse or promote products derived from
36 * this software without specific prior written permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
39 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
42 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
43 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
44 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
45 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
46 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
48 * POSSIBILITY OF SUCH DAMAGE.
49 */
50
51 #include "common.h"
52
53 #include "_pkcs11h-core.h"
54 #include "_pkcs11h-mem.h"
55 #include "_pkcs11h-util.h"
56 #include "_pkcs11h-token.h"
57 #include "_pkcs11h-certificate.h"
58
59 #define __PKCS11H_SERIALIZE_INVALID_CHARS "\\/\"'%&#@!?$* <>{}[]()`|:;,.+-"
60
61 #if defined(ENABLE_PKCS11H_TOKEN) || defined(ENABLE_PKCS11H_CERTIFICATE)
62
63 CK_RV
pkcs11h_token_serializeTokenId(OUT char * const sz,IN OUT size_t * max,IN const pkcs11h_token_id_t token_id)64 pkcs11h_token_serializeTokenId (
65 OUT char * const sz,
66 IN OUT size_t *max,
67 IN const pkcs11h_token_id_t token_id
68 ) {
69 const char *sources[5];
70 CK_RV rv = CKR_FUNCTION_FAILED;
71 size_t n;
72 int e;
73
74 /*_PKCS11H_ASSERT (sz!=NULL); Not required*/
75 _PKCS11H_ASSERT (max!=NULL);
76 _PKCS11H_ASSERT (token_id!=NULL);
77
78 { /* Must be after assert */
79 sources[0] = token_id->manufacturerID;
80 sources[1] = token_id->model;
81 sources[2] = token_id->serialNumber;
82 sources[3] = token_id->label;
83 sources[4] = NULL;
84 }
85
86 _PKCS11H_DEBUG (
87 PKCS11H_LOG_DEBUG2,
88 "PKCS#11: pkcs11h_token_serializeTokenId entry sz=%p, *max="P_Z", token_id=%p",
89 sz,
90 sz != NULL ? *max : 0,
91 (void *)token_id
92 );
93
94 n = 0;
95 for (e=0;sources[e] != NULL;e++) {
96 size_t t;
97 if (
98 (rv = _pkcs11h_util_escapeString (
99 NULL,
100 sources[e],
101 &t,
102 __PKCS11H_SERIALIZE_INVALID_CHARS
103 )) != CKR_OK
104 ) {
105 goto cleanup;
106 }
107 n+=t;
108 }
109
110 if (sz != NULL) {
111 if (*max < n) {
112 rv = CKR_ATTRIBUTE_VALUE_INVALID;
113 goto cleanup;
114 }
115
116 n = 0;
117 for (e=0;sources[e] != NULL;e++) {
118 size_t t = *max-n;
119 if (
120 (rv = _pkcs11h_util_escapeString (
121 sz+n,
122 sources[e],
123 &t,
124 __PKCS11H_SERIALIZE_INVALID_CHARS
125 )) != CKR_OK
126 ) {
127 goto cleanup;
128 }
129 n+=t;
130 sz[n-1] = '/';
131 }
132 sz[n-1] = '\x0';
133 }
134
135 *max = n;
136 rv = CKR_OK;
137
138 cleanup:
139
140 _PKCS11H_DEBUG (
141 PKCS11H_LOG_DEBUG2,
142 "PKCS#11: pkcs11h_token_serializeTokenId return rv=%lu-'%s', *max="P_Z", sz='%s'",
143 rv,
144 pkcs11h_getMessage (rv),
145 *max,
146 sz
147 );
148
149 return rv;
150 }
151
152 CK_RV
pkcs11h_token_deserializeTokenId(OUT pkcs11h_token_id_t * p_token_id,IN const char * const sz)153 pkcs11h_token_deserializeTokenId (
154 OUT pkcs11h_token_id_t *p_token_id,
155 IN const char * const sz
156 ) {
157 #define __PKCS11H_TARGETS_NUMBER 4
158 struct {
159 char *p;
160 size_t s;
161 } targets[__PKCS11H_TARGETS_NUMBER];
162
163 pkcs11h_token_id_t token_id = NULL;
164 char *p1 = NULL;
165 char *_sz = NULL;
166 int e;
167 CK_RV rv = CKR_FUNCTION_FAILED;
168
169 _PKCS11H_ASSERT (p_token_id!=NULL);
170 _PKCS11H_ASSERT (sz!=NULL);
171
172 _PKCS11H_DEBUG (
173 PKCS11H_LOG_DEBUG2,
174 "PKCS#11: pkcs11h_token_deserializeTokenId entry p_token_id=%p, sz='%s'",
175 (void *)p_token_id,
176 sz
177 );
178
179 *p_token_id = NULL;
180
181 if (
182 (rv = _pkcs11h_mem_strdup (
183 (void *)&_sz,
184 sz
185 )) != CKR_OK
186 ) {
187 goto cleanup;
188 }
189
190 p1 = _sz;
191
192 if ((rv = _pkcs11h_token_newTokenId (&token_id)) != CKR_OK) {
193 goto cleanup;
194 }
195
196 targets[0].p = token_id->manufacturerID;
197 targets[0].s = sizeof (token_id->manufacturerID);
198 targets[1].p = token_id->model;
199 targets[1].s = sizeof (token_id->model);
200 targets[2].p = token_id->serialNumber;
201 targets[2].s = sizeof (token_id->serialNumber);
202 targets[3].p = token_id->label;
203 targets[3].s = sizeof (token_id->label);
204
205 for (e=0;e < __PKCS11H_TARGETS_NUMBER;e++) {
206 size_t l;
207 char *p2 = NULL;
208
209 /*
210 * Don't search for last
211 * separator
212 */
213 if (e != __PKCS11H_TARGETS_NUMBER-1) {
214 p2 = strchr (p1, '/');
215 if (p2 == NULL) {
216 rv = CKR_ATTRIBUTE_VALUE_INVALID;
217 goto cleanup;
218 }
219 else {
220 *p2 = '\x0';
221 }
222 }
223
224 if (
225 (rv = _pkcs11h_util_unescapeString (
226 NULL,
227 p1,
228 &l
229 )) != CKR_OK
230 ) {
231 goto cleanup;
232 }
233
234 if (l > targets[e].s) {
235 rv = CKR_ATTRIBUTE_VALUE_INVALID;
236 goto cleanup;
237 }
238
239 l = targets[e].s;
240
241 if (
242 (rv = _pkcs11h_util_unescapeString (
243 targets[e].p,
244 p1,
245 &l
246 )) != CKR_OK
247 ) {
248 goto cleanup;
249 }
250
251 p1 = p2+1;
252 }
253
254 strncpy (
255 token_id->display,
256 token_id->label,
257 sizeof (token_id->display)
258 );
259
260 *p_token_id = token_id;
261 token_id = NULL;
262
263 rv = CKR_OK;
264
265 cleanup:
266
267 if (_sz != NULL) {
268 _pkcs11h_mem_free ((void *)&_sz);
269 }
270
271 if (token_id != NULL) {
272 pkcs11h_token_freeTokenId (token_id);
273 }
274
275 _PKCS11H_DEBUG (
276 PKCS11H_LOG_DEBUG2,
277 "PKCS#11: pkcs11h_token_deserializeTokenId return rv=%lu-'%s'",
278 rv,
279 pkcs11h_getMessage (rv)
280 );
281
282 return rv;
283 #undef __PKCS11H_TARGETS_NUMBER
284 }
285
286 #endif /* ENABLE_PKCS11H_TOKEN || ENABLE_PKCS11H_CERTIFICATE */
287
288 #if defined(ENABLE_PKCS11H_CERTIFICATE)
289
290 CK_RV
pkcs11h_certificate_serializeCertificateId(OUT char * const sz,IN OUT size_t * max,IN const pkcs11h_certificate_id_t certificate_id)291 pkcs11h_certificate_serializeCertificateId (
292 OUT char * const sz,
293 IN OUT size_t *max,
294 IN const pkcs11h_certificate_id_t certificate_id
295 ) {
296 CK_RV rv = CKR_FUNCTION_FAILED;
297 size_t saved_max = 0;
298 size_t n = 0;
299 size_t _max = 0;
300
301 /*_PKCS11H_ASSERT (sz!=NULL); Not required */
302 _PKCS11H_ASSERT (max!=NULL);
303 _PKCS11H_ASSERT (certificate_id!=NULL);
304
305 _PKCS11H_DEBUG (
306 PKCS11H_LOG_DEBUG2,
307 "PKCS#11: pkcs11h_certificate_serializeCertificateId entry sz=%p, *max="P_Z", certificate_id=%p",
308 sz,
309 sz != NULL ? *max : 0,
310 (void *)certificate_id
311 );
312
313 if (sz != NULL) {
314 saved_max = n = *max;
315 }
316 *max = 0;
317
318 if (
319 (rv = pkcs11h_token_serializeTokenId (
320 sz,
321 &n,
322 certificate_id->token_id
323 )) != CKR_OK
324 ) {
325 goto cleanup;
326 }
327
328 _max = n + certificate_id->attrCKA_ID_size*2 + 1;
329
330 if (sz != NULL) {
331 if (saved_max < _max) {
332 rv = CKR_ATTRIBUTE_VALUE_INVALID;
333 goto cleanup;
334 }
335
336 sz[n-1] = '/';
337 rv = _pkcs11h_util_binaryToHex (
338 sz+n,
339 saved_max-n,
340 certificate_id->attrCKA_ID,
341 certificate_id->attrCKA_ID_size
342 );
343 }
344
345 *max = _max;
346 rv = CKR_OK;
347
348 cleanup:
349
350 _PKCS11H_DEBUG (
351 PKCS11H_LOG_DEBUG2,
352 "PKCS#11: pkcs11h_certificate_serializeCertificateId return rv=%lu-'%s', *max="P_Z", sz='%s'",
353 rv,
354 pkcs11h_getMessage (rv),
355 *max,
356 sz
357 );
358
359 return rv;
360 }
361
362 CK_RV
pkcs11h_certificate_deserializeCertificateId(OUT pkcs11h_certificate_id_t * const p_certificate_id,IN const char * const sz)363 pkcs11h_certificate_deserializeCertificateId (
364 OUT pkcs11h_certificate_id_t * const p_certificate_id,
365 IN const char * const sz
366 ) {
367 pkcs11h_certificate_id_t certificate_id = NULL;
368 CK_RV rv = CKR_FUNCTION_FAILED;
369 char *p = NULL;
370 char *_sz = NULL;
371
372 _PKCS11H_ASSERT (p_certificate_id!=NULL);
373 _PKCS11H_ASSERT (sz!=NULL);
374
375 *p_certificate_id = NULL;
376
377 _PKCS11H_DEBUG (
378 PKCS11H_LOG_DEBUG2,
379 "PKCS#11: pkcs11h_certificate_deserializeCertificateId entry p_certificate_id=%p, sz='%s'",
380 (void *)p_certificate_id,
381 sz
382 );
383
384 if (
385 (rv = _pkcs11h_mem_strdup (
386 (void *)&_sz,
387 sz
388 )) != CKR_OK
389 ) {
390 goto cleanup;
391 }
392
393 p = _sz;
394
395 if ((rv = _pkcs11h_certificate_newCertificateId (&certificate_id)) != CKR_OK) {
396 goto cleanup;
397 }
398
399 if ((p = strrchr (_sz, '/')) == NULL) {
400 rv = CKR_ATTRIBUTE_VALUE_INVALID;
401 goto cleanup;
402 }
403
404 *p = '\x0';
405 p++;
406
407 if (
408 (rv = pkcs11h_token_deserializeTokenId (
409 &certificate_id->token_id,
410 _sz
411 )) != CKR_OK
412 ) {
413 goto cleanup;
414 }
415
416 certificate_id->attrCKA_ID_size = strlen (p)/2;
417
418 if (
419 (rv = _pkcs11h_mem_malloc (
420 (void *)&certificate_id->attrCKA_ID,
421 certificate_id->attrCKA_ID_size)
422 ) != CKR_OK ||
423 (rv = _pkcs11h_util_hexToBinary (
424 certificate_id->attrCKA_ID,
425 p,
426 &certificate_id->attrCKA_ID_size
427 )) != CKR_OK
428 ) {
429 goto cleanup;
430 }
431
432 *p_certificate_id = certificate_id;
433 certificate_id = NULL;
434 rv = CKR_OK;
435
436 cleanup:
437
438 if (certificate_id != NULL) {
439 pkcs11h_certificate_freeCertificateId (certificate_id);
440 certificate_id = NULL;
441 }
442
443 if (_sz != NULL) {
444 _pkcs11h_mem_free ((void *)&_sz);
445 }
446
447 _PKCS11H_DEBUG (
448 PKCS11H_LOG_DEBUG2,
449 "PKCS#11: pkcs11h_certificate_deserializeCertificateId return rv=%lu-'%s'",
450 rv,
451 pkcs11h_getMessage (rv)
452 );
453
454 return rv;
455
456 }
457
458 #endif /* ENABLE_PKCS11H_CERTIFICATE */
459
460