Browse code

contrib/vcpkg-ports: add pkcs11-helper port

pkcs11-helper is a dependency library used by OpenVPN.
So far it has been built only by mingw.

Since we're making MSVC build system a first class citizen,
we need to build depencencies with MSVC, which we do with vcpkg.
All dependencies are in vcpkg official repo, expect pkcs11-helper.

This provides vcpkg port for building pkcs11-helper.

Example usage:

vcpkg --overlay-ports=<openvpn>\contrib\vcpkg-ports install pkcs11-helper

Signed-off-by: Lev Stipakov <lev@openvpn.net>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20210607104213.216-1-lstipakov@gmail.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg22503.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Lev Stipakov authored on 2021/06/07 19:42:13
Showing 4 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,88 @@
0
+From 324026ce179468fcea348e59259dbc5456438ead Mon Sep 17 00:00:00 2001
1
+From: Lev Stipakov <lev@openvpn.net>
2
+Date: Fri, 14 May 2021 14:35:53 +0300
3
+Subject: [PATCH] nmake: openssl 1.1.1 support
4
+
5
+Starting from version 1.1.1, OpenSSL includes routines
6
+like RSA_meth_xxx and DSA_meth_xxx. pkcs11-helper includes
7
+implementation of those routines. That code is compiled if
8
+they're missing from OpenSSL.
9
+
10
+nmake build uses pre-generated config-w32-vc.h, which lacks
11
+defines which indicate that OpenSSL includes above routines,
12
+which causes pkcs11's own implementaion to be compiled. However,
13
+pkcs11-helper implementation is not compatible with OpenSSL 1.1.1 -
14
+for example, it takes size of opaque struct RSA_METHOD, which
15
+has become internal in OpenSSL.
16
+
17
+This adds necessary defines to config header used by nmake build
18
+so that pkcs11-helper code, which is not compatible with OpenSSL 1.1.1,
19
+is not compiled.
20
+
21
+Also libeay is changed to libcrypto.
22
+
23
+Signed-off-by: Lev Stipakov <lev@openvpn.net>
24
+---
25
+ config-w32-vc.h.in  | 33 +++++++++++++++++++++++++++++++++
26
+ lib/Makefile.w32-vc |  4 ++--
27
+ 2 files changed, 35 insertions(+), 2 deletions(-)
28
+
29
+diff --git a/config-w32-vc.h b/config-w32-vc.h
30
+index 6346f02..102b2e3 100644
31
+--- a/config-w32-vc.h
32
+@@ -185,3 +185,36 @@
33
+ #if _MSC_VER >= 1400
34
+ #define HAVE_CPP_VARARG_MACRO_ISO 1
35
+ #endif
36
++
37
++/* Define to 1 if you have the `RSA_meth_dup' function. */
38
++#define HAVE_RSA_METH_DUP 1
39
++
40
++/* Define to 1 if you have the `RSA_meth_free' function. */
41
++#define HAVE_RSA_METH_FREE 1
42
++
43
++/* Define to 1 if you have the `RSA_meth_set1_name' function. */
44
++#define HAVE_RSA_METH_SET1_NAME 1
45
++
46
++/* Define to 1 if you have the `RSA_meth_set_flags' function. */
47
++#define HAVE_RSA_METH_SET_FLAGS 1
48
++
49
++/* Define to 1 if you have the `RSA_meth_set_priv_dec' function. */
50
++#define HAVE_RSA_METH_SET_PRIV_DEC 1
51
++
52
++/* Define to 1 if you have the `RSA_meth_set_priv_enc' function. */
53
++#define HAVE_RSA_METH_SET_PRIV_ENC 1
54
++
55
++/* Define to 1 if you have the `DSA_meth_dup' function. */
56
++#define HAVE_DSA_METH_DUP 1
57
++
58
++/* Define to 1 if you have the `DSA_meth_free' function. */
59
++#define HAVE_DSA_METH_FREE 1
60
++
61
++/* Define to 1 if you have the `DSA_meth_set1_name' function. */
62
++#define HAVE_DSA_METH_SET1_NAME 1
63
++
64
++/* Define to 1 if you have the `DSA_meth_set_sign' function. */
65
++#define HAVE_DSA_METH_SET_SIGN 1
66
++
67
++/* Define to 1 if you have the `DSA_SIG_set0' function. */
68
++#define HAVE_DSA_SIG_SET0 1
69
+diff --git a/lib/Makefile.w32-vc b/lib/Makefile.w32-vc
70
+index 2edab39..b2ac746 100644
71
+--- a/lib/Makefile.w32-vc
72
+@@ -60,9 +60,9 @@ OPENSSL_HOME = ..\..\openssl-0.9.8a
73
+ !endif
74
+
75
+ !ifdef OPENSSL
76
+-OPENSSL_STATIC = libeay32.lib
77
++OPENSSL_STATIC = libcrypto.lib
78
+ #OPENSSL_STATIC = libeay32sd.lib
79
+-OPENSSL_DYNAMIC = libeay32.lib
80
++OPENSSL_DYNAMIC = libcrypto.lib
81
+ #OPENSSL_DYNAMIC = libeay32d.lib
82
+
83
+ OPENSSL_INC=$(OPENSSL_HOME)\include
84
+--
85
+2.23.0.windows.1
0 86
new file mode 100644
... ...
@@ -0,0 +1,4 @@
0
+Source: pkcs11-helper
1
+Version: 1.27-1
2
+Homepage: https://github.com/OpenSC/pkcs11-helper
3
+Description: pkcs11-helper is a library that simplifies the interaction with PKCS#11 providers for end-user applications.
0 4
new file mode 100644
... ...
@@ -0,0 +1,686 @@
0
+commit 90590b02085edc3830bdfe0942a46c4e7bf3f1ab (HEAD -> master)
1
+Author: David Woodhouse <David.Woodhouse@intel.com>
2
+Date:   Thu Apr 30 14:58:24 2015 +0100
3
+
4
+    Serialize to RFC7512-compliant PKCS#11 URIs
5
+
6
+    Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
7
+
8
+commit 4d5280da8df591aab701dff4493d13a835a9b29c
9
+Author: David Woodhouse <David.Woodhouse@intel.com>
10
+Date:   Wed Dec 10 14:00:21 2014 +0000
11
+
12
+    Accept RFC7512-compliant PKCS#11 URIs as serialized token/certificate IDs
13
+
14
+    The old format is still accepted for compatibility.
15
+
16
+    Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
17
+
18
+commit 14e09211c3d50eb06825090c9765e4382cf52f19
19
+Author: David Woodhouse <David.Woodhouse@intel.com>
20
+Date:   Sun Dec 14 19:42:18 2014 +0000
21
+
22
+    Stop _pkcs11h_util_hexToBinary() checking for trailing NUL
23
+
24
+    We are going to want to use this for parsing %XX hex escapes in RFC7512
25
+    PKCS#11 URIs, where we cannot expect a trailing NUL. Since there's only
26
+    one existing caller at the moment, it's simple just to let the caller
27
+    have responsibility for that check.
28
+
29
+    Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
30
+diff --git a/lib/pkcs11h-serialization.c b/lib/pkcs11h-serialization.c
31
+index ad275f8..1d077e4 100644
32
+--- a/lib/pkcs11h-serialization.c
33
+@@ -61,29 +61,127 @@
34
+
35
+ #if defined(ENABLE_PKCS11H_TOKEN) || defined(ENABLE_PKCS11H_CERTIFICATE)
36
+
37
++#define URI_SCHEME "pkcs11:"
38
++
39
++#define token_field_ofs(field) ((unsigned long)&(((struct pkcs11h_token_id_s *)0)->field))
40
++#define token_field_size(field) sizeof((((struct pkcs11h_token_id_s *)0)->field))
41
++#define token_field(name, field) { name "=", sizeof(name), \
42
++				   token_field_ofs(field), token_field_size(field) }
43
++
44
++static struct {
45
++	const char const *name;
46
++	size_t namelen;
47
++	unsigned long field_ofs;
48
++	size_t field_size;
49
++} __token_fields[] = {
50
++	token_field ("model", model),
51
++	token_field ("token", label),
52
++	token_field ("manufacturer", manufacturerID ),
53
++	token_field ("serial", serialNumber ),
54
++	{ NULL },
55
++};
56
++
57
++#define               P11_URL_VERBATIM      "abcdefghijklmnopqrstuvwxyz" \
58
++                                            "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
59
++                                            "0123456789_-."
60
++
61
++static
62
++int
63
++__token_attr_escape(char *uri, char *attr, size_t attrlen)
64
++{
65
++	int len = 0, i;
66
++
67
++	for (i = 0; i < attrlen; i++) {
68
++		if ((attr[i] != '\x0') && strchr(P11_URL_VERBATIM, attr[i])) {
69
++			if (uri) {
70
++				*(uri++) = attr[i];
71
++			}
72
++			len++;
73
++		} else {
74
++			if (uri) {
75
++				sprintf(uri, "%%%02x", (unsigned char)attr[i]);
76
++				uri += 3;
77
++			}
78
++			len += 3;
79
++		}
80
++	}
81
++	return len;
82
++}
83
++
84
++static
85
++CK_RV
86
++__generate_pkcs11_uri (
87
++	OUT char * const sz,
88
++	IN OUT size_t *max,
89
++	IN const pkcs11h_certificate_id_t certificate_id,
90
++	IN const pkcs11h_token_id_t token_id
91
++) {
92
++	size_t _max;
93
++	char *p = sz;
94
++	int i;
95
++
96
++	_PKCS11H_ASSERT (max!=NULL);
97
++	_PKCS11H_ASSERT (token_id!=NULL);
98
++
99
++	_max = strlen(URI_SCHEME);
100
++	for (i = 0; __token_fields[i].name; i++) {
101
++		char *field = ((char *)token_id) + __token_fields[i].field_ofs;
102
++
103
++		_max += __token_fields[i].namelen;
104
++		_max += __token_attr_escape (NULL, field, strlen(field));
105
++		_max++; /* For a semicolon or trailing NUL */
106
++	}
107
++	if (certificate_id) {
108
++		_max += strlen (";id=");
109
++		_max += __token_attr_escape (NULL,
110
++					     (char *)certificate_id->attrCKA_ID,
111
++					     certificate_id->attrCKA_ID_size);
112
++	}
113
++
114
++	if (!sz) {
115
++		*max = _max;
116
++		return CKR_OK;
117
++	}
118
++
119
++	if (sz && *max < _max)
120
++		return CKR_ATTRIBUTE_VALUE_INVALID;
121
++
122
++	p += sprintf(p, URI_SCHEME);
123
++	for (i = 0; __token_fields[i].name; i++) {
124
++		char *field = ((char *)token_id) + __token_fields[i].field_ofs;
125
++
126
++		p += sprintf (p, "%s", __token_fields[i].name);
127
++		p += __token_attr_escape (p, field, strlen(field));
128
++		*(p++) = ';';
129
++	}
130
++	if (certificate_id) {
131
++		p += sprintf (p, "id=");
132
++		p += __token_attr_escape (p,
133
++					  (char *)certificate_id->attrCKA_ID,
134
++					  certificate_id->attrCKA_ID_size);
135
++	} else {
136
++		/* Remove the unneeded trailing semicolon */
137
++		p--;
138
++	}
139
++	*(p++) = 0;
140
++
141
++	*max = _max;
142
++
143
++	return CKR_OK;
144
++}
145
++
146
+ CK_RV
147
+ pkcs11h_token_serializeTokenId (
148
+	OUT char * const sz,
149
+	IN OUT size_t *max,
150
+	IN const pkcs11h_token_id_t token_id
151
+ ) {
152
+-	const char *sources[5];
153
+	CK_RV rv = CKR_FUNCTION_FAILED;
154
+-	size_t n;
155
+-	int e;
156
+
157
+	/*_PKCS11H_ASSERT (sz!=NULL); Not required*/
158
+	_PKCS11H_ASSERT (max!=NULL);
159
+	_PKCS11H_ASSERT (token_id!=NULL);
160
+
161
+-	{ /* Must be after assert */
162
+-		sources[0] = token_id->manufacturerID;
163
+-		sources[1] = token_id->model;
164
+-		sources[2] = token_id->serialNumber;
165
+-		sources[3] = token_id->label;
166
+-		sources[4] = NULL;
167
+-	}
168
+-
169
+	_PKCS11H_DEBUG (
170
+		PKCS11H_LOG_DEBUG2,
171
+		"PKCS#11: pkcs11h_token_serializeTokenId entry sz=%p, *max="P_Z", token_id=%p",
172
+@@ -92,67 +190,161 @@ pkcs11h_token_serializeTokenId (
173
+		(void *)token_id
174
+	);
175
+
176
+-	n = 0;
177
+-	for (e=0;sources[e] != NULL;e++) {
178
+-		size_t t;
179
+-		if (
180
+-			(rv = _pkcs11h_util_escapeString (
181
+-				NULL,
182
+-				sources[e],
183
+-				&t,
184
+-				__PKCS11H_SERIALIZE_INVALID_CHARS
185
+-			)) != CKR_OK
186
+-		) {
187
+-			goto cleanup;
188
++	rv = __generate_pkcs11_uri(sz, max, NULL, token_id);
189
++
190
++	_PKCS11H_DEBUG (
191
++		PKCS11H_LOG_DEBUG2,
192
++		"PKCS#11: pkcs11h_token_serializeTokenId return rv=%lu-'%s', *max="P_Z", sz='%s'",
193
++		rv,
194
++		pkcs11h_getMessage (rv),
195
++		*max,
196
++		sz
197
++	);
198
++
199
++	return rv;
200
++}
201
++
202
++static
203
++CK_RV
204
++__parse_token_uri_attr (
205
++	const char *uri,
206
++	size_t urilen,
207
++	char *tokstr,
208
++	size_t toklen,
209
++	size_t *parsed_len
210
++) {
211
++	size_t orig_toklen = toklen;
212
++	CK_RV rv = CKR_OK;
213
++
214
++	while (urilen && toklen > 1) {
215
++		if (*uri == '%') {
216
++			size_t size = 1;
217
++
218
++			if (urilen < 3) {
219
++				rv = CKR_ATTRIBUTE_VALUE_INVALID;
220
++				goto done;
221
++			}
222
++
223
++			rv = _pkcs11h_util_hexToBinary ((unsigned char *)tokstr,
224
++							uri + 1, &size);
225
++			if (rv != CKR_OK) {
226
++				goto done;
227
++			}
228
++
229
++			uri += 2;
230
++			urilen -= 2;
231
++		} else {
232
++			*tokstr = *uri;
233
+		}
234
+-		n+=t;
235
++		tokstr++;
236
++		uri++;
237
++		toklen--;
238
++		urilen--;
239
++		tokstr[0] = 0;
240
+	}
241
+
242
+-	if (sz != NULL) {
243
+-		if (*max < n) {
244
+-			rv = CKR_ATTRIBUTE_VALUE_INVALID;
245
+-			goto cleanup;
246
++	if (urilen) {
247
++		rv = CKR_ATTRIBUTE_VALUE_INVALID;
248
++	} else if (parsed_len) {
249
++		*parsed_len = orig_toklen - toklen;
250
++	}
251
++
252
++ done:
253
++	return rv;
254
++}
255
++
256
++static
257
++CK_RV
258
++__parse_pkcs11_uri (
259
++	OUT pkcs11h_token_id_t token_id,
260
++	OUT pkcs11h_certificate_id_t certificate_id,
261
++	IN const char * const sz
262
++) {
263
++	const char *end, *p;
264
++	CK_RV rv = CKR_OK;
265
++
266
++	_PKCS11H_ASSERT (token_id!=NULL);
267
++	_PKCS11H_ASSERT (sz!=NULL);
268
++
269
++	if (strncmp (sz, URI_SCHEME, strlen (URI_SCHEME)))
270
++		return CKR_ATTRIBUTE_VALUE_INVALID;
271
++
272
++	end = sz + strlen (URI_SCHEME) - 1;
273
++	while (rv == CKR_OK && end[0] && end[1]) {
274
++		int i;
275
++
276
++		p = end + 1;
277
++	        end = strchr (p, ';');
278
++		if (!end)
279
++			end = p + strlen(p);
280
++
281
++		for (i = 0; __token_fields[i].name; i++) {
282
++			/* Parse the token=, label=, manufacturer= and serial= fields */
283
++			if (!strncmp(p, __token_fields[i].name, __token_fields[i].namelen)) {
284
++				char *field = ((char *)token_id) + __token_fields[i].field_ofs;
285
++
286
++				p += __token_fields[i].namelen;
287
++				rv = __parse_token_uri_attr (p, end - p, field,
288
++							     __token_fields[i].field_size,
289
++							     NULL);
290
++				if (rv != CKR_OK) {
291
++					goto cleanup;
292
++				}
293
++
294
++				goto matched;
295
++			}
296
+		}
297
++		if (certificate_id && !strncmp(p, "id=", 3)) {
298
++			p += 3;
299
++
300
++			rv = _pkcs11h_mem_malloc ((void *)&certificate_id->attrCKA_ID,
301
++						  end - p + 1);
302
++			if (rv != CKR_OK) {
303
++				goto cleanup;
304
++			}
305
+
306
+-		n = 0;
307
+-		for (e=0;sources[e] != NULL;e++) {
308
+-			size_t t = *max-n;
309
+-			if (
310
+-				(rv = _pkcs11h_util_escapeString (
311
+-					sz+n,
312
+-					sources[e],
313
+-					&t,
314
+-					__PKCS11H_SERIALIZE_INVALID_CHARS
315
+-				)) != CKR_OK
316
+-			) {
317
++			rv = __parse_token_uri_attr (p, end - p,
318
++						     (char *)certificate_id->attrCKA_ID,
319
++						     end - p + 1,
320
++						     &certificate_id->attrCKA_ID_size);
321
++			if (rv != CKR_OK) {
322
+				goto cleanup;
323
+			}
324
+-			n+=t;
325
+-			sz[n-1] = '/';
326
++
327
++			goto matched;
328
+		}
329
+-		sz[n-1] = '\x0';
330
+-	}
331
+
332
+-	*max = n;
333
+-	rv = CKR_OK;
334
++		/* We don't parse object= because the match code doesn't support
335
++		   matching by label. */
336
++
337
++		/* Failed to parse PKCS#11 URI element. */
338
++		return CKR_ATTRIBUTE_VALUE_INVALID;
339
+
340
++		matched:
341
++		    ;
342
++	}
343
+ cleanup:
344
++	/* The matching code doesn't support support partial matches; it needs
345
++	 * *all* of manufacturer, model, serial and label attributes to be
346
++	 * defined. So reject partial URIs early instead of letting it do the
347
++	 * wrong thing. We can maybe improve this later. */
348
++	if (!token_id->model[0] || !token_id->label[0] ||
349
++	    !token_id->manufacturerID[0] || !token_id->serialNumber[0]) {
350
++		return CKR_ATTRIBUTE_VALUE_INVALID;
351
++	}
352
+
353
+-	_PKCS11H_DEBUG (
354
+-		PKCS11H_LOG_DEBUG2,
355
+-		"PKCS#11: pkcs11h_token_serializeTokenId return rv=%lu-'%s', *max="P_Z", sz='%s'",
356
+-		rv,
357
+-		pkcs11h_getMessage (rv),
358
+-		*max,
359
+-		sz
360
+-	);
361
++	/* For a certificate ID we need CKA_ID */
362
++	if (certificate_id && !certificate_id->attrCKA_ID_size) {
363
++		return CKR_ATTRIBUTE_VALUE_INVALID;
364
++	}
365
+
366
+	return rv;
367
+ }
368
+
369
++static
370
+ CK_RV
371
+-pkcs11h_token_deserializeTokenId (
372
+-	OUT pkcs11h_token_id_t *p_token_id,
373
++__pkcs11h_token_legacy_deserializeTokenId (
374
++	OUT pkcs11h_token_id_t token_id,
375
+	IN const char * const sz
376
+ ) {
377
+ #define __PKCS11H_TARGETS_NUMBER 4
378
+@@ -161,24 +353,11 @@ pkcs11h_token_deserializeTokenId (
379
+		size_t s;
380
+	} targets[__PKCS11H_TARGETS_NUMBER];
381
+
382
+-	pkcs11h_token_id_t token_id = NULL;
383
+	char *p1 = NULL;
384
+	char *_sz = NULL;
385
+	int e;
386
+	CK_RV rv = CKR_FUNCTION_FAILED;
387
+
388
+-	_PKCS11H_ASSERT (p_token_id!=NULL);
389
+-	_PKCS11H_ASSERT (sz!=NULL);
390
+-
391
+-	_PKCS11H_DEBUG (
392
+-		PKCS11H_LOG_DEBUG2,
393
+-		"PKCS#11: pkcs11h_token_deserializeTokenId entry p_token_id=%p, sz='%s'",
394
+-		(void *)p_token_id,
395
+-		sz
396
+-	);
397
+-
398
+-	*p_token_id = NULL;
399
+-
400
+	if (
401
+		(rv = _pkcs11h_mem_strdup (
402
+			(void *)&_sz,
403
+@@ -190,10 +369,6 @@ pkcs11h_token_deserializeTokenId (
404
+
405
+	p1 = _sz;
406
+
407
+-	if ((rv = _pkcs11h_token_newTokenId (&token_id)) != CKR_OK) {
408
+-		goto cleanup;
409
+-	}
410
+-
411
+	targets[0].p = token_id->manufacturerID;
412
+	targets[0].s = sizeof (token_id->manufacturerID);
413
+	targets[1].p = token_id->model;
414
+@@ -252,6 +427,51 @@ pkcs11h_token_deserializeTokenId (
415
+		p1 = p2+1;
416
+	}
417
+
418
++	rv = CKR_OK;
419
++
420
++cleanup:
421
++
422
++	if (_sz != NULL) {
423
++		_pkcs11h_mem_free ((void *)&_sz);
424
++	}
425
++
426
++	return rv;
427
++#undef __PKCS11H_TARGETS_NUMBER
428
++}
429
++
430
++CK_RV
431
++pkcs11h_token_deserializeTokenId (
432
++	OUT pkcs11h_token_id_t *p_token_id,
433
++	IN const char * const sz
434
++) {
435
++	pkcs11h_token_id_t token_id = NULL;
436
++	CK_RV rv = CKR_FUNCTION_FAILED;
437
++
438
++	_PKCS11H_ASSERT (p_token_id!=NULL);
439
++	_PKCS11H_ASSERT (sz!=NULL);
440
++
441
++	_PKCS11H_DEBUG (
442
++		PKCS11H_LOG_DEBUG2,
443
++		"PKCS#11: pkcs11h_token_deserializeTokenId entry p_token_id=%p, sz='%s'",
444
++		(void *)p_token_id,
445
++		sz
446
++	);
447
++
448
++	*p_token_id = NULL;
449
++
450
++	if ((rv = _pkcs11h_token_newTokenId (&token_id)) != CKR_OK) {
451
++		goto cleanup;
452
++	}
453
++
454
++	if (!strncmp (sz, URI_SCHEME, strlen (URI_SCHEME))) {
455
++		rv = __parse_pkcs11_uri(token_id, NULL, sz);
456
++	} else {
457
++		rv = __pkcs11h_token_legacy_deserializeTokenId(token_id, sz);
458
++	}
459
++	if (rv != CKR_OK) {
460
++		goto cleanup;
461
++	}
462
++
463
+	strncpy (
464
+		token_id->display,
465
+		token_id->label,
466
+@@ -264,11 +484,6 @@ pkcs11h_token_deserializeTokenId (
467
+	rv = CKR_OK;
468
+
469
+ cleanup:
470
+-
471
+-	if (_sz != NULL) {
472
+-		_pkcs11h_mem_free ((void *)&_sz);
473
+-	}
474
+-
475
+	if (token_id != NULL) {
476
+		pkcs11h_token_freeTokenId (token_id);
477
+	}
478
+@@ -281,7 +496,6 @@ cleanup:
479
+	);
480
+
481
+	return rv;
482
+-#undef __PKCS11H_TARGETS_NUMBER
483
+ }
484
+
485
+ #endif				/* ENABLE_PKCS11H_TOKEN || ENABLE_PKCS11H_CERTIFICATE */
486
+@@ -295,9 +509,6 @@ pkcs11h_certificate_serializeCertificateId (
487
+	IN const pkcs11h_certificate_id_t certificate_id
488
+ ) {
489
+	CK_RV rv = CKR_FUNCTION_FAILED;
490
+-	size_t saved_max = 0;
491
+-	size_t n = 0;
492
+-	size_t _max = 0;
493
+
494
+	/*_PKCS11H_ASSERT (sz!=NULL); Not required */
495
+	_PKCS11H_ASSERT (max!=NULL);
496
+@@ -311,42 +522,7 @@ pkcs11h_certificate_serializeCertificateId (
497
+		(void *)certificate_id
498
+	);
499
+
500
+-	if (sz != NULL) {
501
+-		saved_max = n = *max;
502
+-	}
503
+-	*max = 0;
504
+-
505
+-	if (
506
+-		(rv = pkcs11h_token_serializeTokenId (
507
+-			sz,
508
+-			&n,
509
+-			certificate_id->token_id
510
+-		)) != CKR_OK
511
+-	) {
512
+-		goto cleanup;
513
+-	}
514
+-
515
+-	_max = n + certificate_id->attrCKA_ID_size*2 + 1;
516
+-
517
+-	if (sz != NULL) {
518
+-		if (saved_max < _max) {
519
+-			rv = CKR_ATTRIBUTE_VALUE_INVALID;
520
+-			goto cleanup;
521
+-		}
522
+-
523
+-		sz[n-1] = '/';
524
+-		rv = _pkcs11h_util_binaryToHex (
525
+-			sz+n,
526
+-			saved_max-n,
527
+-			certificate_id->attrCKA_ID,
528
+-			certificate_id->attrCKA_ID_size
529
+-		);
530
+-	}
531
+-
532
+-	*max = _max;
533
+-	rv = CKR_OK;
534
+-
535
+-cleanup:
536
++	rv = __generate_pkcs11_uri(sz, max, certificate_id, certificate_id->token_id);
537
+
538
+	_PKCS11H_DEBUG (
539
+		PKCS11H_LOG_DEBUG2,
540
+@@ -360,27 +536,16 @@ cleanup:
541
+	return rv;
542
+ }
543
+
544
++static
545
+ CK_RV
546
+-pkcs11h_certificate_deserializeCertificateId (
547
+-	OUT pkcs11h_certificate_id_t * const p_certificate_id,
548
++__pkcs11h_certificate_legacy_deserializeCertificateId (
549
++	OUT pkcs11h_certificate_id_t certificate_id,
550
+	IN const char * const sz
551
+ ) {
552
+-	pkcs11h_certificate_id_t certificate_id = NULL;
553
+	CK_RV rv = CKR_FUNCTION_FAILED;
554
+	char *p = NULL;
555
+	char *_sz = NULL;
556
+-
557
+-	_PKCS11H_ASSERT (p_certificate_id!=NULL);
558
+-	_PKCS11H_ASSERT (sz!=NULL);
559
+-
560
+-	*p_certificate_id = NULL;
561
+-
562
+-	_PKCS11H_DEBUG (
563
+-		PKCS11H_LOG_DEBUG2,
564
+-		"PKCS#11: pkcs11h_certificate_deserializeCertificateId entry p_certificate_id=%p, sz='%s'",
565
+-		(void *)p_certificate_id,
566
+-		sz
567
+-	);
568
++	size_t id_hex_len;
569
+
570
+	if (
571
+		(rv = _pkcs11h_mem_strdup (
572
+@@ -393,10 +558,6 @@ pkcs11h_certificate_deserializeCertificateId (
573
+
574
+	p = _sz;
575
+
576
+-	if ((rv = _pkcs11h_certificate_newCertificateId (&certificate_id)) != CKR_OK) {
577
+-		goto cleanup;
578
+-	}
579
+-
580
+	if ((p = strrchr (_sz, '/')) == NULL) {
581
+		rv = CKR_ATTRIBUTE_VALUE_INVALID;
582
+		goto cleanup;
583
+@@ -414,7 +575,12 @@ pkcs11h_certificate_deserializeCertificateId (
584
+		goto cleanup;
585
+	}
586
+
587
+-	certificate_id->attrCKA_ID_size = strlen (p)/2;
588
++	id_hex_len = strlen (p);
589
++	if (id_hex_len & 1) {
590
++		rv = CKR_ATTRIBUTE_VALUE_INVALID;
591
++		goto cleanup;
592
++	}
593
++	certificate_id->attrCKA_ID_size = id_hex_len/2;
594
+
595
+	if (
596
+		(rv = _pkcs11h_mem_malloc (
597
+@@ -430,21 +596,64 @@ pkcs11h_certificate_deserializeCertificateId (
598
+		goto cleanup;
599
+	}
600
+
601
++	rv = CKR_OK;
602
++
603
++cleanup:
604
++
605
++	if (_sz != NULL) {
606
++		_pkcs11h_mem_free ((void *)&_sz);
607
++	}
608
++
609
++	return rv;
610
++
611
++}
612
++
613
++CK_RV
614
++pkcs11h_certificate_deserializeCertificateId (
615
++	OUT pkcs11h_certificate_id_t * const p_certificate_id,
616
++	IN const char * const sz
617
++) {
618
++	pkcs11h_certificate_id_t certificate_id = NULL;
619
++	CK_RV rv = CKR_FUNCTION_FAILED;
620
++
621
++	_PKCS11H_ASSERT (p_certificate_id!=NULL);
622
++	_PKCS11H_ASSERT (sz!=NULL);
623
++
624
++	*p_certificate_id = NULL;
625
++
626
++	_PKCS11H_DEBUG (
627
++		PKCS11H_LOG_DEBUG2,
628
++		"PKCS#11: pkcs11h_certificate_deserializeCertificateId entry p_certificate_id=%p, sz='%s'",
629
++		(void *)p_certificate_id,
630
++		sz
631
++	);
632
++
633
++	if ((rv = _pkcs11h_certificate_newCertificateId (&certificate_id)) != CKR_OK) {
634
++		goto cleanup;
635
++	}
636
++	if ((rv = _pkcs11h_token_newTokenId (&certificate_id->token_id)) != CKR_OK) {
637
++		goto cleanup;
638
++	}
639
++
640
++	if (!strncmp(sz, URI_SCHEME, strlen (URI_SCHEME))) {
641
++		rv = __parse_pkcs11_uri (certificate_id->token_id, certificate_id, sz);
642
++	} else {
643
++		rv = __pkcs11h_certificate_legacy_deserializeCertificateId (certificate_id, sz);
644
++	}
645
++	if (rv != CKR_OK) {
646
++		goto cleanup;
647
++	}
648
++
649
+	*p_certificate_id = certificate_id;
650
+	certificate_id = NULL;
651
+	rv = CKR_OK;
652
+
653
+ cleanup:
654
+-
655
+	if (certificate_id != NULL) {
656
+		pkcs11h_certificate_freeCertificateId (certificate_id);
657
+		certificate_id = NULL;
658
+	}
659
+
660
+-	if (_sz != NULL) {
661
+-		_pkcs11h_mem_free ((void *)&_sz);
662
+-	}
663
+-
664
+	_PKCS11H_DEBUG (
665
+		PKCS11H_LOG_DEBUG2,
666
+		"PKCS#11: pkcs11h_certificate_deserializeCertificateId return rv=%lu-'%s'",
667
+diff --git a/lib/pkcs11h-util.c b/lib/pkcs11h-util.c
668
+index 0743fd1..f90e443 100644
669
+--- a/lib/pkcs11h-util.c
670
+@@ -110,12 +110,7 @@ _pkcs11h_util_hexToBinary (
671
+		p++;
672
+	}
673
+
674
+-	if (*p != '\x0') {
675
+-		return CKR_ATTRIBUTE_VALUE_INVALID;
676
+-	}
677
+-	else {
678
+-		return CKR_OK;
679
+-	}
680
++	return CKR_OK;
681
+ }
682
+
683
+ CK_RV
0 684
new file mode 100644
... ...
@@ -0,0 +1,35 @@
0
+set(VERSION 1.27)
1
+
2
+vcpkg_download_distfile(ARCHIVE
3
+    URLS "https://github.com/OpenSC/pkcs11-helper/releases/download/pkcs11-helper-${VERSION}/pkcs11-helper-${VERSION}.0.tar.bz2"
4
+    FILENAME "pkcs11-helper-${VERSION}.tar.bz2"
5
+    SHA512 5799342cb755dae8b7ba0880d652e9d4b4f1e52a74043015e1185e1e059326cb2689bb51957db98060ac2257dee34e2f047dcf3d52ad59fd49b91fedcfc5332b
6
+)
7
+
8
+vcpkg_extract_source_archive_ex(
9
+    OUT_SOURCE_PATH SOURCE_PATH
10
+    ARCHIVE ${ARCHIVE}
11
+    REF ${VERSION}
12
+    PATCHES
13
+        0001-nmake-openssl-1.1.1-support.patch
14
+        pkcs11-helper-001-RFC7512.patch
15
+)
16
+
17
+vcpkg_build_nmake(
18
+    SOURCE_PATH ${SOURCE_PATH}
19
+    NO_DEBUG
20
+    PROJECT_SUBPATH lib
21
+    PROJECT_NAME Makefile.w32-vc
22
+    OPTIONS
23
+        OPENSSL=1
24
+        OPENSSL_HOME=${CURRENT_PACKAGES_DIR}/../openssl_${TARGET_TRIPLET}
25
+)
26
+
27
+file(INSTALL ${SOURCE_PATH}/include/pkcs11-helper-1.0 DESTINATION ${CURRENT_PACKAGES_DIR}/include/)
28
+file(INSTALL ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}/lib/pkcs11-helper.dll.lib DESTINATION ${CURRENT_PACKAGES_DIR}/lib)
29
+file(INSTALL ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}/lib/pkcs11-helper.dll.lib DESTINATION ${CURRENT_PACKAGES_DIR}/debug/lib)
30
+
31
+file(INSTALL ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}/lib/libpkcs11-helper-1.dll DESTINATION ${CURRENT_PACKAGES_DIR}/bin)
32
+file(INSTALL ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}/lib/libpkcs11-helper-1.dll DESTINATION ${CURRENT_PACKAGES_DIR}/debug/bin)
33
+
34
+file(INSTALL ${SOURCE_PATH}/COPYING DESTINATION ${CURRENT_PACKAGES_DIR}/share/${PORT} RENAME copyright)