1 /*
2 * GnuTLS PKCS#11 support
3 * Copyright (C) 2010-2012 Free Software Foundation, Inc.
4 *
5 * Authors: Nikos Mavrogiannopoulos, Stef Walter
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>
19 */
20
21 #include "gnutls_int.h"
22 #include <gnutls/pkcs11.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include "errors.h"
26 #include <datum.h>
27 #include <pkcs11_int.h>
28 #include "pkcs11x.h"
29 #include <x509/common.h>
30 #include "pk.h"
31
32 static const ck_bool_t tval = 1;
33 static const ck_bool_t fval = 0;
34
35 #define MAX_ASIZE 24
36
mark_flags(unsigned flags,struct ck_attribute * a,unsigned * a_val,unsigned trusted)37 static void mark_flags(unsigned flags, struct ck_attribute *a, unsigned *a_val, unsigned trusted)
38 {
39 static const unsigned long category = 2;
40
41 if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_CA) {
42 a[*a_val].type = CKA_CERTIFICATE_CATEGORY;
43 a[*a_val].value = (void *) &category;
44 a[*a_val].value_len = sizeof(category);
45 (*a_val)++;
46 }
47
48 if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_DISTRUSTED) {
49 if (trusted) {
50 a[*a_val].type = CKA_X_DISTRUSTED;
51 a[*a_val].value = (void *) &tval;
52 a[*a_val].value_len = sizeof(tval);
53 (*a_val)++;
54 } else {
55 _gnutls_debug_log("p11: ignoring the distrusted flag as it is not valid on non-p11-kit-trust modules\n");
56 }
57 }
58
59 if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED) {
60 a[*a_val].type = CKA_TRUSTED;
61 a[*a_val].value = (void *) &tval;
62 a[*a_val].value_len = sizeof(tval);
63 (*a_val)++;
64
65 a[*a_val].type = CKA_PRIVATE;
66 a[*a_val].value = (void *) &fval;
67 a[*a_val].value_len = sizeof(fval);
68 (*a_val)++;
69 } else {
70 if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE) {
71 a[*a_val].type = CKA_PRIVATE;
72 a[*a_val].value = (void *) &tval;
73 a[*a_val].value_len = sizeof(tval);
74 (*a_val)++;
75 } else if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE) {
76 a[*a_val].type = CKA_PRIVATE;
77 a[*a_val].value = (void *) &fval;
78 a[*a_val].value_len = sizeof(fval);
79 (*a_val)++;
80 }
81 }
82 }
83
84 /**
85 * gnutls_pkcs11_copy_x509_crt2:
86 * @token_url: A PKCS #11 URL specifying a token
87 * @crt: The certificate to copy
88 * @label: The name to be used for the stored data
89 * @cid: The CKA_ID to set for the object -if NULL, the ID will be derived from the public key
90 * @flags: One of GNUTLS_PKCS11_OBJ_FLAG_*
91 *
92 * This function will copy a certificate into a PKCS #11 token specified by
93 * a URL. Valid flags to mark the certificate: %GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED,
94 * %GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE, %GNUTLS_PKCS11_OBJ_FLAG_MARK_CA,
95 * %GNUTLS_PKCS11_OBJ_FLAG_MARK_ALWAYS_AUTH.
96 *
97 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
98 * negative error value.
99 *
100 * Since: 3.4.0
101 **/
102 int
gnutls_pkcs11_copy_x509_crt2(const char * token_url,gnutls_x509_crt_t crt,const char * label,const gnutls_datum_t * cid,unsigned int flags)103 gnutls_pkcs11_copy_x509_crt2(const char *token_url,
104 gnutls_x509_crt_t crt, const char *label,
105 const gnutls_datum_t *cid,
106 unsigned int flags)
107 {
108 int ret;
109 struct p11_kit_uri *info = NULL;
110 ck_rv_t rv;
111 size_t der_size, id_size, serial_size;
112 gnutls_datum_t serial_der = {NULL, 0};
113 uint8_t *der = NULL;
114 uint8_t serial[128];
115 uint8_t id[20];
116 struct ck_attribute a[MAX_ASIZE];
117 ck_object_class_t class = CKO_CERTIFICATE;
118 ck_certificate_type_t type = CKC_X_509;
119 ck_object_handle_t ctx;
120 unsigned a_val;
121 struct pkcs11_session_info sinfo;
122
123 PKCS11_CHECK_INIT;
124
125 ret = pkcs11_url_to_info(token_url, &info, 0);
126 if (ret < 0) {
127 gnutls_assert();
128 return ret;
129 }
130
131 ret =
132 pkcs11_open_session(&sinfo, NULL, info,
133 SESSION_WRITE |
134 pkcs11_obj_flags_to_int(flags));
135 p11_kit_uri_free(info);
136
137 if (ret < 0) {
138 gnutls_assert();
139 return ret;
140 }
141
142 der_size = 0;
143 ret =
144 gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_DER, NULL,
145 &der_size);
146 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
147 gnutls_assert();
148 goto cleanup;
149 }
150
151 der = gnutls_malloc(der_size);
152 if (der == NULL) {
153 gnutls_assert();
154 ret = GNUTLS_E_MEMORY_ERROR;
155 goto cleanup;
156 }
157
158 ret =
159 gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_DER, der,
160 &der_size);
161 if (ret < 0) {
162 gnutls_assert();
163 goto cleanup;
164 }
165
166 a[0].type = CKA_CLASS;
167 a[0].value = &class;
168 a[0].value_len = sizeof(class);
169
170 a[1].type = CKA_ID;
171 if (cid == NULL || cid->size == 0) {
172 id_size = sizeof(id);
173 ret = gnutls_x509_crt_get_subject_key_id(crt, id, &id_size, NULL);
174 if (ret < 0) {
175 id_size = sizeof(id);
176 ret = gnutls_x509_crt_get_key_id(crt, 0, id, &id_size);
177 if (ret < 0) {
178 gnutls_assert();
179 goto cleanup;
180 }
181 }
182
183 a[1].value = id;
184 a[1].value_len = id_size;
185 } else {
186 a[1].value = cid->data;
187 a[1].value_len = cid->size;
188 }
189
190 /* we do not use the key usage flags; these are apparent from
191 * the certificate itself. */
192 a[2].type = CKA_VALUE;
193 a[2].value = der;
194 a[2].value_len = der_size;
195 a[3].type = CKA_TOKEN;
196 a[3].value = (void *) &tval;
197 a[3].value_len = sizeof(tval);
198 a[4].type = CKA_CERTIFICATE_TYPE;
199 a[4].value = &type;
200 a[4].value_len = sizeof(type);
201
202 a_val = 5;
203
204 a[a_val].type = CKA_SUBJECT;
205 a[a_val].value = crt->raw_dn.data;
206 a[a_val].value_len = crt->raw_dn.size;
207 a_val++;
208
209 if (crt->raw_issuer_dn.size > 0) {
210 a[a_val].type = CKA_ISSUER;
211 a[a_val].value = crt->raw_issuer_dn.data;
212 a[a_val].value_len = crt->raw_issuer_dn.size;
213 a_val++;
214 }
215
216 serial_size = sizeof(serial);
217 if (gnutls_x509_crt_get_serial(crt, serial, &serial_size) >= 0) {
218 ret = _gnutls_x509_ext_gen_number(serial, serial_size, &serial_der);
219 if (ret >= 0) {
220 a[a_val].type = CKA_SERIAL_NUMBER;
221 a[a_val].value = (void *) serial_der.data;
222 a[a_val].value_len = serial_der.size;
223 a_val++;
224 }
225 }
226
227 if (label) {
228 a[a_val].type = CKA_LABEL;
229 a[a_val].value = (void *) label;
230 a[a_val].value_len = strlen(label);
231 a_val++;
232 }
233
234 mark_flags(flags, a, &a_val, sinfo.trusted);
235
236 rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_val, &ctx);
237 if (rv != CKR_OK) {
238 gnutls_assert();
239 _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
240 ret = pkcs11_rv_to_err(rv);
241 goto cleanup;
242 }
243
244 /* generated!
245 */
246
247 ret = 0;
248
249 cleanup:
250 gnutls_free(der);
251 gnutls_free(serial_der.data);
252 pkcs11_close_session(&sinfo);
253 return ret;
254
255 }
256
clean_pubkey(struct ck_attribute * a,unsigned a_val)257 static void clean_pubkey(struct ck_attribute *a, unsigned a_val)
258 {
259 unsigned i;
260
261 for (i=0;i<a_val;i++) {
262 switch(a[i].type) {
263 case CKA_MODULUS:
264 case CKA_PUBLIC_EXPONENT:
265 case CKA_PRIME:
266 case CKA_SUBPRIME:
267 case CKA_VALUE:
268 case CKA_BASE:
269 case CKA_EC_PARAMS:
270 case CKA_EC_POINT:
271 gnutls_free(a[i].value);
272 break;
273 }
274 }
275 }
276
add_pubkey(gnutls_pubkey_t pubkey,struct ck_attribute * a,unsigned * a_val)277 static int add_pubkey(gnutls_pubkey_t pubkey, struct ck_attribute *a, unsigned *a_val)
278 {
279 gnutls_pk_algorithm_t pk;
280 int ret;
281
282 pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL);
283
284 switch (pk) {
285 case GNUTLS_PK_RSA_PSS:
286 case GNUTLS_PK_RSA: {
287 gnutls_datum_t m, e;
288
289 /* PKCS#11 defines integers as unsigned having most significant byte
290 * first, e.g., 32768 = 0x80 0x00. This is interpreted literraly by
291 * some HSMs which do not accept an integer with a leading zero */
292 ret = gnutls_pubkey_export_rsa_raw2(pubkey, &m, &e, GNUTLS_EXPORT_FLAG_NO_LZ);
293 if (ret < 0) {
294 gnutls_assert();
295 return ret;
296 }
297
298
299 a[*a_val].type = CKA_MODULUS;
300 a[*a_val].value = m.data;
301 a[*a_val].value_len = m.size;
302 (*a_val)++;
303
304 a[*a_val].type = CKA_PUBLIC_EXPONENT;
305 a[*a_val].value = e.data;
306 a[*a_val].value_len = e.size;
307 (*a_val)++;
308 break;
309 }
310 case GNUTLS_PK_DSA: {
311 gnutls_datum_t p, q, g, y;
312
313 ret = gnutls_pubkey_export_dsa_raw2(pubkey, &p, &q, &g, &y, GNUTLS_EXPORT_FLAG_NO_LZ);
314 if (ret < 0) {
315 gnutls_assert();
316 return ret;
317 }
318
319 a[*a_val].type = CKA_PRIME;
320 a[*a_val].value = p.data;
321 a[*a_val].value_len = p.size;
322 (*a_val)++;
323
324 a[*a_val].type = CKA_SUBPRIME;
325 a[*a_val].value = q.data;
326 a[*a_val].value_len = q.size;
327 (*a_val)++;
328
329 a[*a_val].type = CKA_BASE;
330 a[*a_val].value = g.data;
331 a[*a_val].value_len = g.size;
332 (*a_val)++;
333
334 a[*a_val].type = CKA_VALUE;
335 a[*a_val].value = y.data;
336 a[*a_val].value_len = y.size;
337 (*a_val)++;
338 break;
339 }
340 case GNUTLS_PK_EC: {
341 gnutls_datum_t params, point;
342
343 ret = gnutls_pubkey_export_ecc_x962(pubkey, ¶ms, &point);
344 if (ret < 0) {
345 gnutls_assert();
346 return ret;
347 }
348
349 a[*a_val].type = CKA_EC_PARAMS;
350 a[*a_val].value = params.data;
351 a[*a_val].value_len = params.size;
352 (*a_val)++;
353
354 a[*a_val].type = CKA_EC_POINT;
355 a[*a_val].value = point.data;
356 a[*a_val].value_len = point.size;
357 (*a_val)++;
358 break;
359 }
360 case GNUTLS_PK_EDDSA_ED25519: {
361 gnutls_datum_t params, ecpoint;
362
363 ret =
364 _gnutls_x509_write_ecc_params(pubkey->params.curve,
365 ¶ms);
366 if (ret < 0) {
367 gnutls_assert();
368 return ret;
369 }
370
371 a[*a_val].type = CKA_EC_PARAMS;
372 a[*a_val].value = params.data;
373 a[*a_val].value_len = params.size;
374 (*a_val)++;
375
376 ret = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING,
377 pubkey->params.raw_pub.data,
378 pubkey->params.raw_pub.size,
379 &ecpoint);
380 if (ret < 0) {
381 gnutls_assert();
382 return ret;
383 }
384
385 a[*a_val].type = CKA_EC_POINT;
386 a[*a_val].value = ecpoint.data;
387 a[*a_val].value_len = ecpoint.size;
388 (*a_val)++;
389 break;
390 }
391
392 default:
393 _gnutls_debug_log("requested writing public key of unsupported type %u\n", (unsigned)pk);
394 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
395 }
396
397 return 0;
398 }
399
400 /**
401 * gnutls_pkcs11_copy_pubkey:
402 * @token_url: A PKCS #11 URL specifying a token
403 * @pubkey: The public key to copy
404 * @label: The name to be used for the stored data
405 * @cid: The CKA_ID to set for the object -if NULL, the ID will be derived from the public key
406 * @key_usage: One of GNUTLS_KEY_*
407 * @flags: One of GNUTLS_PKCS11_OBJ_FLAG_*
408 *
409 * This function will copy a public key object into a PKCS #11 token specified by
410 * a URL. Valid flags to mark the key: %GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED,
411 * %GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE, %GNUTLS_PKCS11_OBJ_FLAG_MARK_CA,
412 * %GNUTLS_PKCS11_OBJ_FLAG_MARK_ALWAYS_AUTH.
413 *
414 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
415 * negative error value.
416 *
417 * Since: 3.4.6
418 **/
419 int
gnutls_pkcs11_copy_pubkey(const char * token_url,gnutls_pubkey_t pubkey,const char * label,const gnutls_datum_t * cid,unsigned int key_usage,unsigned int flags)420 gnutls_pkcs11_copy_pubkey(const char *token_url,
421 gnutls_pubkey_t pubkey, const char *label,
422 const gnutls_datum_t *cid,
423 unsigned int key_usage, unsigned int flags)
424 {
425 int ret;
426 struct p11_kit_uri *info = NULL;
427 ck_rv_t rv;
428 size_t id_size;
429 uint8_t id[20];
430 struct ck_attribute a[MAX_ASIZE];
431 gnutls_pk_algorithm_t pk;
432 ck_object_class_t class = CKO_PUBLIC_KEY;
433 ck_object_handle_t ctx;
434 unsigned a_val;
435 ck_key_type_t type;
436 struct pkcs11_session_info sinfo;
437
438 PKCS11_CHECK_INIT;
439
440 ret = pkcs11_url_to_info(token_url, &info, 0);
441 if (ret < 0) {
442 gnutls_assert();
443 return ret;
444 }
445
446 ret =
447 pkcs11_open_session(&sinfo, NULL, info,
448 SESSION_WRITE |
449 pkcs11_obj_flags_to_int(flags));
450 p11_kit_uri_free(info);
451
452 if (ret < 0) {
453 gnutls_assert();
454 return ret;
455 }
456
457 a[0].type = CKA_CLASS;
458 a[0].value = &class;
459 a[0].value_len = sizeof(class);
460
461 a[1].type = CKA_TOKEN;
462 a[1].value = (void *) &tval;
463 a[1].value_len = sizeof(tval);
464
465 a_val = 2;
466
467 ret = add_pubkey(pubkey, a, &a_val);
468 if (ret < 0) {
469 gnutls_assert();
470 goto cleanup;
471 }
472
473 if (label) {
474 a[a_val].type = CKA_LABEL;
475 a[a_val].value = (void *) label;
476 a[a_val].value_len = strlen(label);
477 a_val++;
478 }
479
480 pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL);
481 type = pk_to_key_type(pk);
482 FIX_KEY_USAGE(pk, key_usage);
483
484 a[a_val].type = CKA_KEY_TYPE;
485 a[a_val].value = &type;
486 a[a_val].value_len = sizeof(type);
487 a_val++;
488
489 a[a_val].type = CKA_ID;
490 if (cid == NULL || cid->size == 0) {
491 id_size = sizeof(id);
492 ret = gnutls_pubkey_get_key_id(pubkey, 0, id, &id_size);
493 if (ret < 0) {
494 gnutls_assert();
495 goto cleanup;
496 }
497
498 a[a_val].value = id;
499 a[a_val].value_len = id_size;
500 } else {
501 a[a_val].value = cid->data;
502 a[a_val].value_len = cid->size;
503 }
504 a_val++;
505
506 mark_flags(flags, a, &a_val, sinfo.trusted);
507
508 a[a_val].type = CKA_VERIFY;
509 if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE) {
510 a[a_val].value = (void*)&tval;
511 a[a_val].value_len = sizeof(tval);
512 } else {
513 a[a_val].value = (void*)&fval;
514 a[a_val].value_len = sizeof(fval);
515 }
516 a_val++;
517
518 if (pk == GNUTLS_PK_RSA) {
519 a[a_val].type = CKA_ENCRYPT;
520 if (key_usage & (GNUTLS_KEY_ENCIPHER_ONLY|GNUTLS_KEY_DECIPHER_ONLY)) {
521 a[a_val].value = (void*)&tval;
522 a[a_val].value_len = sizeof(tval);
523 } else {
524 a[a_val].value = (void*)&fval;
525 a[a_val].value_len = sizeof(fval);
526 }
527 a_val++;
528 }
529
530 rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_val, &ctx);
531 if (rv != CKR_OK) {
532 gnutls_assert();
533 _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
534 ret = pkcs11_rv_to_err(rv);
535 goto cleanup;
536 }
537
538 /* generated!
539 */
540
541 ret = 0;
542
543 cleanup:
544 clean_pubkey(a, a_val);
545 pkcs11_close_session(&sinfo);
546 return ret;
547
548 }
549
550
551 /**
552 * gnutls_pkcs11_copy_attached_extension:
553 * @token_url: A PKCS #11 URL specifying a token
554 * @crt: An X.509 certificate object
555 * @data: the attached extension
556 * @label: A name to be used for the attached extension (may be %NULL)
557 * @flags: One of GNUTLS_PKCS11_OBJ_FLAG_*
558 *
559 * This function will copy an the attached extension in @data for
560 * the certificate provided in @crt in the PKCS #11 token specified
561 * by the URL (typically a trust module). The extension must be in
562 * RFC5280 Extension format.
563 *
564 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
565 * negative error value.
566 *
567 * Since: 3.3.8
568 **/
569 int
gnutls_pkcs11_copy_attached_extension(const char * token_url,gnutls_x509_crt_t crt,gnutls_datum_t * data,const char * label,unsigned int flags)570 gnutls_pkcs11_copy_attached_extension(const char *token_url,
571 gnutls_x509_crt_t crt,
572 gnutls_datum_t *data,
573 const char *label,
574 unsigned int flags)
575 {
576 int ret;
577 struct p11_kit_uri *info = NULL;
578 ck_rv_t rv;
579 struct ck_attribute a[MAX_ASIZE];
580 ck_object_handle_t ctx;
581 unsigned a_vals;
582 struct pkcs11_session_info sinfo;
583 ck_object_class_t class;
584 gnutls_datum_t spki = {NULL, 0};
585
586 PKCS11_CHECK_INIT;
587
588 ret = pkcs11_url_to_info(token_url, &info, 0);
589 if (ret < 0) {
590 gnutls_assert();
591 return ret;
592 }
593
594 ret =
595 pkcs11_open_session(&sinfo, NULL, info,
596 SESSION_WRITE |
597 pkcs11_obj_flags_to_int(flags));
598 p11_kit_uri_free(info);
599
600 if (ret < 0) {
601 gnutls_assert();
602 return ret;
603 }
604
605 ret = x509_crt_to_raw_pubkey(crt, &spki);
606 if (ret < 0) {
607 gnutls_assert();
608 goto cleanup;
609 }
610
611 class = CKO_X_CERTIFICATE_EXTENSION;
612 a_vals = 0;
613 a[a_vals].type = CKA_CLASS;
614 a[a_vals].value = &class;
615 a[a_vals++].value_len = sizeof(class);
616
617 a[a_vals].type = CKA_PUBLIC_KEY_INFO;
618 a[a_vals].value = spki.data;
619 a[a_vals++].value_len = spki.size;
620
621 a[a_vals].type = CKA_VALUE;
622 a[a_vals].value = data->data;
623 a[a_vals++].value_len = data->size;
624
625 a[a_vals].type = CKA_TOKEN;
626 a[a_vals].value = (void *) &tval;
627 a[a_vals++].value_len = sizeof(tval);
628
629 if (label) {
630 a[a_vals].type = CKA_LABEL;
631 a[a_vals].value = (void *) label;
632 a[a_vals++].value_len = strlen(label);
633 }
634
635 rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_vals, &ctx);
636 if (rv != CKR_OK) {
637 gnutls_assert();
638 _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
639 ret = pkcs11_rv_to_err(rv);
640 goto cleanup;
641 }
642
643 ret = 0;
644
645 cleanup:
646 pkcs11_close_session(&sinfo);
647 gnutls_free(spki.data);
648 return ret;
649
650 }
651
652 /**
653 * gnutls_pkcs11_copy_x509_privkey2:
654 * @token_url: A PKCS #11 URL specifying a token
655 * @key: A private key
656 * @label: A name to be used for the stored data
657 * @cid: The CKA_ID to set for the object -if NULL, the ID will be derived from the public key
658 * @key_usage: One of GNUTLS_KEY_*
659 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
660 *
661 * This function will copy a private key into a PKCS #11 token specified by
662 * a URL.
663 *
664 * Since 3.6.3 the objects are marked as sensitive by default unless
665 * %GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_SENSITIVE is specified.
666 *
667 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
668 * negative error value.
669 *
670 * Since: 3.4.0
671 **/
672 int
gnutls_pkcs11_copy_x509_privkey2(const char * token_url,gnutls_x509_privkey_t key,const char * label,const gnutls_datum_t * cid,unsigned int key_usage,unsigned int flags)673 gnutls_pkcs11_copy_x509_privkey2(const char *token_url,
674 gnutls_x509_privkey_t key,
675 const char *label,
676 const gnutls_datum_t *cid,
677 unsigned int key_usage, unsigned int flags)
678 {
679 int ret;
680 struct p11_kit_uri *info = NULL;
681 ck_rv_t rv;
682 size_t id_size;
683 uint8_t id[20];
684 struct ck_attribute a[32];
685 ck_object_class_t class = CKO_PRIVATE_KEY;
686 ck_object_handle_t ctx;
687 ck_key_type_t type;
688 int a_val;
689 gnutls_pk_algorithm_t pk;
690 gnutls_datum_t p, q, g, y, x;
691 gnutls_datum_t m, e, d, u, exp1, exp2;
692 struct pkcs11_session_info sinfo;
693
694 PKCS11_CHECK_INIT;
695
696 memset(&p, 0, sizeof(p));
697 memset(&q, 0, sizeof(q));
698 memset(&g, 0, sizeof(g));
699 memset(&y, 0, sizeof(y));
700 memset(&x, 0, sizeof(x));
701 memset(&m, 0, sizeof(m));
702 memset(&e, 0, sizeof(e));
703 memset(&d, 0, sizeof(d));
704 memset(&u, 0, sizeof(u));
705 memset(&exp1, 0, sizeof(exp1));
706 memset(&exp2, 0, sizeof(exp2));
707
708 ret = pkcs11_url_to_info(token_url, &info, 0);
709 if (ret < 0) {
710 gnutls_assert();
711 return ret;
712 }
713
714 ret =
715 pkcs11_open_session(&sinfo, NULL, info,
716 SESSION_WRITE |
717 pkcs11_obj_flags_to_int(flags));
718 p11_kit_uri_free(info);
719
720 if (ret < 0) {
721 gnutls_assert();
722 return ret;
723 }
724
725 pk = gnutls_x509_privkey_get_pk_algorithm(key);
726 FIX_KEY_USAGE(pk, key_usage);
727
728 a_val = 0;
729 a[a_val].type = CKA_CLASS;
730 a[a_val].value = &class;
731 a[a_val].value_len = sizeof(class);
732 a_val++;
733
734 a[a_val].type = CKA_ID;
735 if (cid == NULL || cid->size == 0) {
736 id_size = sizeof(id);
737 ret = gnutls_x509_privkey_get_key_id(key, 0, id, &id_size);
738 if (ret < 0) {
739 p11_kit_uri_free(info);
740 gnutls_assert();
741 return ret;
742 }
743
744 a[a_val].value = id;
745 a[a_val].value_len = id_size;
746 } else {
747 a[a_val].value = cid->data;
748 a[a_val].value_len = cid->size;
749 }
750 a_val++;
751
752 a[a_val].type = CKA_SIGN;
753 if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE) {
754 a[a_val].value = (void*)&tval;
755 a[a_val].value_len = sizeof(tval);
756 } else {
757 a[a_val].value = (void*)&fval;
758 a[a_val].value_len = sizeof(fval);
759 }
760 a_val++;
761
762 if (pk == GNUTLS_PK_RSA) {
763 a[a_val].type = CKA_DECRYPT;
764 if ((key_usage & (GNUTLS_KEY_ENCIPHER_ONLY|GNUTLS_KEY_DECIPHER_ONLY)) ||
765 (key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT)) {
766 a[a_val].value = (void*)&tval;
767 a[a_val].value_len = sizeof(tval);
768 } else {
769 a[a_val].value = (void*)&fval;
770 a[a_val].value_len = sizeof(fval);
771 }
772 a_val++;
773 }
774
775 a[a_val].type = CKA_TOKEN;
776 a[a_val].value = (void *) &tval;
777 a[a_val].value_len = sizeof(tval);
778 a_val++;
779
780 /* a private key is set always as private unless
781 * requested otherwise
782 */
783 if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE) {
784 a[a_val].type = CKA_PRIVATE;
785 a[a_val].value = (void *) &fval;
786 a[a_val].value_len = sizeof(fval);
787 a_val++;
788 } else {
789 a[a_val].type = CKA_PRIVATE;
790 a[a_val].value = (void *) &tval;
791 a[a_val].value_len = sizeof(tval);
792 a_val++;
793 }
794
795 if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_ALWAYS_AUTH) {
796 a[a_val].type = CKA_ALWAYS_AUTHENTICATE;
797 a[a_val].value = (void *) &tval;
798 a[a_val].value_len = sizeof(tval);
799 a_val++;
800 }
801
802 if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_EXTRACTABLE) {
803 a[a_val].type = CKA_EXTRACTABLE;
804 a[a_val].value = (void *) &tval;
805 a[a_val].value_len = sizeof(tval);
806 (a_val)++;
807 } else {
808 a[a_val].type = CKA_EXTRACTABLE;
809 a[a_val].value = (void *) &fval;
810 a[a_val].value_len = sizeof(fval);
811 (a_val)++;
812 }
813
814 if (label) {
815 a[a_val].type = CKA_LABEL;
816 a[a_val].value = (void *) label;
817 a[a_val].value_len = strlen(label);
818 a_val++;
819 }
820
821 if (!(flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_SENSITIVE)) {
822 a[a_val].type = CKA_SENSITIVE;
823 a[a_val].value = (void *) &tval;
824 a[a_val].value_len = sizeof(tval);
825 a_val++;
826 } else {
827 a[a_val].type = CKA_SENSITIVE;
828 a[a_val].value = (void *) &fval;
829 a[a_val].value_len = sizeof(fval);
830 a_val++;
831 }
832
833 switch (pk) {
834 case GNUTLS_PK_RSA:
835 case GNUTLS_PK_RSA_PSS:
836 {
837
838 ret = _gnutls_params_get_rsa_raw(&key->params, &m, &e, &d, &p,
839 &q, &u, &exp1, &exp2,
840 GNUTLS_EXPORT_FLAG_NO_LZ);
841 if (ret < 0) {
842 gnutls_assert();
843 goto cleanup;
844 }
845
846 type = CKK_RSA;
847
848 a[a_val].type = CKA_MODULUS;
849 a[a_val].value = m.data;
850 a[a_val].value_len = m.size;
851 a_val++;
852
853 a[a_val].type = CKA_PUBLIC_EXPONENT;
854 a[a_val].value = e.data;
855 a[a_val].value_len = e.size;
856 a_val++;
857
858 a[a_val].type = CKA_PRIVATE_EXPONENT;
859 a[a_val].value = d.data;
860 a[a_val].value_len = d.size;
861 a_val++;
862
863 a[a_val].type = CKA_PRIME_1;
864 a[a_val].value = p.data;
865 a[a_val].value_len = p.size;
866 a_val++;
867
868 a[a_val].type = CKA_PRIME_2;
869 a[a_val].value = q.data;
870 a[a_val].value_len = q.size;
871 a_val++;
872
873 a[a_val].type = CKA_COEFFICIENT;
874 a[a_val].value = u.data;
875 a[a_val].value_len = u.size;
876 a_val++;
877
878 a[a_val].type = CKA_EXPONENT_1;
879 a[a_val].value = exp1.data;
880 a[a_val].value_len = exp1.size;
881 a_val++;
882
883 a[a_val].type = CKA_EXPONENT_2;
884 a[a_val].value = exp2.data;
885 a[a_val].value_len = exp2.size;
886 a_val++;
887
888 break;
889 }
890 case GNUTLS_PK_DSA:
891 {
892 ret = _gnutls_params_get_dsa_raw(&key->params, &p, &q, &g, &y, &x,
893 GNUTLS_EXPORT_FLAG_NO_LZ);
894 if (ret < 0) {
895 gnutls_assert();
896 goto cleanup;
897 }
898
899 type = CKK_DSA;
900
901 a[a_val].type = CKA_PRIME;
902 a[a_val].value = p.data;
903 a[a_val].value_len = p.size;
904 a_val++;
905
906 a[a_val].type = CKA_SUBPRIME;
907 a[a_val].value = q.data;
908 a[a_val].value_len = q.size;
909 a_val++;
910
911 a[a_val].type = CKA_BASE;
912 a[a_val].value = g.data;
913 a[a_val].value_len = g.size;
914 a_val++;
915
916 a[a_val].type = CKA_VALUE;
917 a[a_val].value = x.data;
918 a[a_val].value_len = x.size;
919 a_val++;
920
921 break;
922 }
923 case GNUTLS_PK_EC:
924 {
925 ret =
926 _gnutls_x509_write_ecc_params(key->params.curve,
927 &p);
928 if (ret < 0) {
929 gnutls_assert();
930 goto cleanup;
931 }
932
933 ret =
934 _gnutls_mpi_dprint(key->params.
935 params[ECC_K], &x);
936 if (ret < 0) {
937 gnutls_assert();
938 goto cleanup;
939 }
940
941 type = CKK_ECDSA;
942
943 a[a_val].type = CKA_EC_PARAMS;
944 a[a_val].value = p.data;
945 a[a_val].value_len = p.size;
946 a_val++;
947
948 a[a_val].type = CKA_VALUE;
949 a[a_val].value = x.data;
950 a[a_val].value_len = x.size;
951 a_val++;
952
953 break;
954 }
955 #ifdef HAVE_CKM_EDDSA
956 case GNUTLS_PK_EDDSA_ED25519:
957 {
958 ret =
959 _gnutls_x509_write_ecc_params(key->params.curve,
960 &p);
961 if (ret < 0) {
962 gnutls_assert();
963 goto cleanup;
964 }
965
966 type = CKK_EC_EDWARDS;
967
968 a[a_val].type = CKA_EC_PARAMS;
969 a[a_val].value = p.data;
970 a[a_val].value_len = p.size;
971 a_val++;
972
973 a[a_val].type = CKA_VALUE;
974 a[a_val].value = key->params.raw_priv.data;
975 a[a_val].value_len = key->params.raw_priv.size;
976 a_val++;
977
978 break;
979 }
980 #endif
981 default:
982 gnutls_assert();
983 ret = GNUTLS_E_INVALID_REQUEST;
984 goto cleanup;
985 }
986
987 a[a_val].type = CKA_KEY_TYPE;
988 a[a_val].value = &type;
989 a[a_val].value_len = sizeof(type);
990 a_val++;
991
992 rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_val, &ctx);
993 if (rv != CKR_OK) {
994 gnutls_assert();
995 _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
996 ret = pkcs11_rv_to_err(rv);
997 goto cleanup;
998 }
999
1000 ret = 0;
1001
1002 cleanup:
1003 switch (pk) {
1004 case GNUTLS_PK_RSA_PSS:
1005 case GNUTLS_PK_RSA:
1006 {
1007 gnutls_free(m.data);
1008 gnutls_free(e.data);
1009 gnutls_free(d.data);
1010 gnutls_free(p.data);
1011 gnutls_free(q.data);
1012 gnutls_free(u.data);
1013 gnutls_free(exp1.data);
1014 gnutls_free(exp2.data);
1015 break;
1016 }
1017 case GNUTLS_PK_DSA:
1018 {
1019 gnutls_free(p.data);
1020 gnutls_free(q.data);
1021 gnutls_free(g.data);
1022 gnutls_free(y.data);
1023 gnutls_free(x.data);
1024 break;
1025 }
1026 case GNUTLS_PK_EC:
1027 case GNUTLS_PK_EDDSA_ED25519:
1028 {
1029 gnutls_free(p.data);
1030 gnutls_free(x.data);
1031 break;
1032 }
1033 default:
1034 gnutls_assert();
1035 ret = GNUTLS_E_INVALID_REQUEST;
1036 break;
1037 }
1038
1039 if (sinfo.pks != 0)
1040 pkcs11_close_session(&sinfo);
1041
1042 return ret;
1043
1044 }
1045
1046 struct delete_data_st {
1047 struct p11_kit_uri *info;
1048 unsigned int deleted; /* how many */
1049 };
1050
1051 static int
delete_obj_url_cb(struct ck_function_list * module,struct pkcs11_session_info * sinfo,struct ck_token_info * tinfo,struct ck_info * lib_info,void * input)1052 delete_obj_url_cb(struct ck_function_list *module, struct pkcs11_session_info *sinfo,
1053 struct ck_token_info *tinfo,
1054 struct ck_info *lib_info, void *input)
1055 {
1056 struct delete_data_st *find_data = input;
1057 struct ck_attribute a[4];
1058 struct ck_attribute *attr;
1059 ck_object_class_t class;
1060 ck_certificate_type_t type = (ck_certificate_type_t) - 1;
1061 ck_rv_t rv;
1062 ck_object_handle_t ctx;
1063 unsigned long count, a_vals;
1064 int found = 0, ret;
1065
1066 if (tinfo == NULL) { /* we don't support multiple calls */
1067 gnutls_assert();
1068 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1069 }
1070
1071 /* do not bother reading the token if basic fields do not match
1072 */
1073 if (!p11_kit_uri_match_module_info(find_data->info, lib_info) ||
1074 !p11_kit_uri_match_token_info(find_data->info, tinfo)) {
1075 gnutls_assert();
1076 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1077 }
1078
1079 /* Find objects with given class and type */
1080 class = CKO_CERTIFICATE; /* default */
1081 a_vals = 0;
1082
1083 attr = p11_kit_uri_get_attribute(find_data->info, CKA_CLASS);
1084 if (attr != NULL) {
1085 if (attr->value
1086 && attr->value_len == sizeof(ck_object_class_t))
1087 class = *((ck_object_class_t *) attr->value);
1088 if (class == CKO_CERTIFICATE)
1089 type = CKC_X_509;
1090
1091 a[a_vals].type = CKA_CLASS;
1092 a[a_vals].value = &class;
1093 a[a_vals].value_len = sizeof(class);
1094 a_vals++;
1095 }
1096
1097 attr = p11_kit_uri_get_attribute(find_data->info, CKA_ID);
1098 if (attr != NULL) {
1099 memcpy(a + a_vals, attr, sizeof(struct ck_attribute));
1100 a_vals++;
1101 }
1102
1103 if (type != (ck_certificate_type_t) - 1) {
1104 a[a_vals].type = CKA_CERTIFICATE_TYPE;
1105 a[a_vals].value = &type;
1106 a[a_vals].value_len = sizeof type;
1107 a_vals++;
1108 }
1109
1110 attr = p11_kit_uri_get_attribute(find_data->info, CKA_LABEL);
1111 if (attr != NULL) {
1112 memcpy(a + a_vals, attr, sizeof(struct ck_attribute));
1113 a_vals++;
1114 }
1115
1116 rv = pkcs11_find_objects_init(sinfo->module, sinfo->pks, a,
1117 a_vals);
1118 if (rv != CKR_OK) {
1119 gnutls_assert();
1120 _gnutls_debug_log("p11: FindObjectsInit failed.\n");
1121 ret = pkcs11_rv_to_err(rv);
1122 goto cleanup;
1123 }
1124
1125 while (pkcs11_find_objects
1126 (sinfo->module, sinfo->pks, &ctx, 1, &count) == CKR_OK
1127 && count == 1) {
1128 rv = pkcs11_destroy_object(sinfo->module, sinfo->pks, ctx);
1129 if (rv != CKR_OK) {
1130 _gnutls_debug_log
1131 ("p11: Cannot destroy object: %s\n",
1132 pkcs11_strerror(rv));
1133 } else {
1134 find_data->deleted++;
1135 }
1136
1137 found = 1;
1138 }
1139
1140 if (found == 0) {
1141 gnutls_assert();
1142 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1143 } else {
1144 ret = 0;
1145 }
1146
1147 cleanup:
1148 pkcs11_find_objects_final(sinfo);
1149
1150 return ret;
1151 }
1152
1153
1154 /**
1155 * gnutls_pkcs11_delete_url:
1156 * @object_url: The URL of the object to delete.
1157 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1158 *
1159 * This function will delete objects matching the given URL.
1160 * Note that not all tokens support the delete operation.
1161 *
1162 * Returns: On success, the number of objects deleted is returned, otherwise a
1163 * negative error value.
1164 *
1165 * Since: 2.12.0
1166 **/
gnutls_pkcs11_delete_url(const char * object_url,unsigned int flags)1167 int gnutls_pkcs11_delete_url(const char *object_url, unsigned int flags)
1168 {
1169 int ret;
1170 struct delete_data_st find_data;
1171
1172 PKCS11_CHECK_INIT;
1173
1174 memset(&find_data, 0, sizeof(find_data));
1175
1176 ret = pkcs11_url_to_info(object_url, &find_data.info, 0);
1177 if (ret < 0) {
1178 gnutls_assert();
1179 return ret;
1180 }
1181
1182 ret =
1183 _pkcs11_traverse_tokens(delete_obj_url_cb, &find_data,
1184 find_data.info, NULL,
1185 SESSION_WRITE |
1186 pkcs11_obj_flags_to_int(flags));
1187 p11_kit_uri_free(find_data.info);
1188
1189 if (ret < 0) {
1190 gnutls_assert();
1191 return ret;
1192 }
1193
1194 return find_data.deleted;
1195
1196 }
1197
1198 /**
1199 * gnutls_pkcs11_token_init:
1200 * @token_url: A PKCS #11 URL specifying a token
1201 * @so_pin: Security Officer's PIN
1202 * @label: A name to be used for the token
1203 *
1204 * This function will initialize (format) a token. If the token is
1205 * at a factory defaults state the security officer's PIN given will be
1206 * set to be the default. Otherwise it should match the officer's PIN.
1207 *
1208 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1209 * negative error value.
1210 **/
1211 int
gnutls_pkcs11_token_init(const char * token_url,const char * so_pin,const char * label)1212 gnutls_pkcs11_token_init(const char *token_url,
1213 const char *so_pin, const char *label)
1214 {
1215 int ret;
1216 struct p11_kit_uri *info = NULL;
1217 ck_rv_t rv;
1218 struct ck_function_list *module;
1219 ck_slot_id_t slot;
1220 char flabel[32];
1221
1222 PKCS11_CHECK_INIT;
1223
1224 ret = pkcs11_url_to_info(token_url, &info, 0);
1225 if (ret < 0) {
1226 gnutls_assert();
1227 return ret;
1228 }
1229
1230 ret = pkcs11_find_slot(&module, &slot, info, NULL, NULL, NULL);
1231 p11_kit_uri_free(info);
1232
1233 if (ret < 0) {
1234 gnutls_assert();
1235 return ret;
1236 }
1237
1238 /* so it seems memset has other uses than zeroing! */
1239 memset(flabel, ' ', sizeof(flabel));
1240 if (label != NULL)
1241 memcpy(flabel, label, strlen(label));
1242
1243 rv = pkcs11_init_token(module, slot, (uint8_t *) so_pin,
1244 strlen(so_pin), (uint8_t *) flabel);
1245 if (rv != CKR_OK) {
1246 gnutls_assert();
1247 _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
1248 return pkcs11_rv_to_err(rv);
1249 }
1250
1251 return 0;
1252
1253 }
1254
1255 #define L(x) ((x==NULL)?0:strlen(x))
1256
1257 /**
1258 * gnutls_pkcs11_token_set_pin:
1259 * @token_url: A PKCS #11 URL specifying a token
1260 * @oldpin: old user's PIN
1261 * @newpin: new user's PIN
1262 * @flags: one of #gnutls_pin_flag_t.
1263 *
1264 * This function will modify or set a user or administrator's PIN for
1265 * the given token. If it is called to set a PIN for first time
1266 * the oldpin must be %NULL. When setting the admin's PIN with the
1267 * %GNUTLS_PIN_SO flag, the @oldpin value must be provided (this requirement
1268 * is relaxed after GnuTLS 3.6.5 since which the PIN will be requested if missing).
1269 *
1270 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1271 * negative error value.
1272 **/
1273 int
gnutls_pkcs11_token_set_pin(const char * token_url,const char * oldpin,const char * newpin,unsigned int flags)1274 gnutls_pkcs11_token_set_pin(const char *token_url,
1275 const char *oldpin,
1276 const char *newpin, unsigned int flags)
1277 {
1278 int ret;
1279 struct p11_kit_uri *info = NULL;
1280 ck_rv_t rv;
1281 unsigned int ses_flags;
1282 struct pkcs11_session_info sinfo;
1283
1284 PKCS11_CHECK_INIT;
1285
1286 ret = pkcs11_url_to_info(token_url, &info, 0);
1287 if (ret < 0) {
1288 gnutls_assert();
1289 return ret;
1290 }
1291
1292 if (((flags & GNUTLS_PIN_USER) && oldpin == NULL) ||
1293 (flags & GNUTLS_PIN_SO))
1294 ses_flags = SESSION_WRITE | SESSION_LOGIN | SESSION_SO;
1295 else
1296 ses_flags = SESSION_WRITE | SESSION_LOGIN;
1297
1298 ret = pkcs11_open_session(&sinfo, NULL, info, ses_flags);
1299 p11_kit_uri_free(info);
1300
1301 if (ret < 0) {
1302 gnutls_assert();
1303 return ret;
1304 }
1305
1306 if (oldpin == NULL && !(flags & GNUTLS_PIN_SO)) {
1307 /* This changes only the user PIN */
1308 rv = pkcs11_init_pin(sinfo.module, sinfo.pks,
1309 (uint8_t *) newpin, strlen(newpin));
1310 if (rv != CKR_OK) {
1311 gnutls_assert();
1312 _gnutls_debug_log("p11: %s\n",
1313 pkcs11_strerror(rv));
1314 ret = pkcs11_rv_to_err(rv);
1315 goto finish;
1316 }
1317 } else {
1318 struct p11_kit_pin *pin;
1319 unsigned oldpin_size;
1320
1321 oldpin_size = L(oldpin);
1322
1323 if (!(sinfo.tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
1324 if (newpin == NULL)
1325 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1326
1327 if (oldpin == NULL) {
1328 struct pin_info_st pin_info;
1329 memset(&pin_info, 0, sizeof(pin_info));
1330
1331 ret = pkcs11_retrieve_pin(&pin_info, info, &sinfo.tinfo, 0, CKU_SO, &pin);
1332 if (ret < 0) {
1333 gnutls_assert();
1334 goto finish;
1335 }
1336 oldpin = (const char*)p11_kit_pin_get_value(pin, NULL);
1337 oldpin_size = p11_kit_pin_get_length(pin);
1338 }
1339 }
1340
1341 rv = pkcs11_set_pin(sinfo.module, sinfo.pks,
1342 oldpin, oldpin_size,
1343 newpin, L(newpin));
1344 if (rv != CKR_OK) {
1345 gnutls_assert();
1346 _gnutls_debug_log("p11: %s\n",
1347 pkcs11_strerror(rv));
1348 ret = pkcs11_rv_to_err(rv);
1349 goto finish;
1350 }
1351 }
1352
1353 ret = 0;
1354
1355 finish:
1356 pkcs11_close_session(&sinfo);
1357 return ret;
1358
1359 }
1360
1361 /**
1362 * gnutls_pkcs11_token_get_random:
1363 * @token_url: A PKCS #11 URL specifying a token
1364 * @len: The number of bytes of randomness to request
1365 * @rnddata: A pointer to the memory area to be filled with random data
1366 *
1367 * This function will get random data from the given token.
1368 * It will store rnddata and fill the memory pointed to by rnddata with
1369 * len random bytes from the token.
1370 *
1371 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1372 * negative error value.
1373 **/
1374 int
gnutls_pkcs11_token_get_random(const char * token_url,void * rnddata,size_t len)1375 gnutls_pkcs11_token_get_random(const char *token_url,
1376 void *rnddata, size_t len)
1377 {
1378 int ret;
1379 struct p11_kit_uri *info = NULL;
1380 ck_rv_t rv;
1381 struct pkcs11_session_info sinfo;
1382
1383 PKCS11_CHECK_INIT;
1384
1385 ret = pkcs11_url_to_info(token_url, &info, 0);
1386 if (ret < 0) {
1387 gnutls_assert();
1388 return ret;
1389 }
1390
1391 ret = pkcs11_open_session(&sinfo, NULL, info, 0);
1392 p11_kit_uri_free(info);
1393
1394 if (ret < 0) {
1395 gnutls_assert();
1396 return ret;
1397 }
1398
1399 rv = _gnutls_pkcs11_get_random(sinfo.module, sinfo.pks, rnddata, len);
1400 if (rv != CKR_OK) {
1401 gnutls_assert();
1402 _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
1403 ret = pkcs11_rv_to_err(rv);
1404 goto finish;
1405 }
1406
1407 ret = 0;
1408
1409 finish:
1410 pkcs11_close_session(&sinfo);
1411 return ret;
1412
1413 }
1414
1415 #if 0
1416 /* For documentation purposes */
1417
1418
1419 /**
1420 * gnutls_pkcs11_copy_x509_crt:
1421 * @token_url: A PKCS #11 URL specifying a token
1422 * @crt: A certificate
1423 * @label: A name to be used for the stored data
1424 * @flags: One of GNUTLS_PKCS11_OBJ_FLAG_*
1425 *
1426 * This function will copy a certificate into a PKCS #11 token specified by
1427 * a URL. The certificate can be marked as trusted or not.
1428 *
1429 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1430 * negative error value.
1431 *
1432 * Since: 2.12.0
1433 **/
1434 int gnutls_pkcs11_copy_x509_crt(const char *token_url,
1435 gnutls_x509_crt_t crt, const char *label,
1436 unsigned int flags)
1437 {
1438 int x;
1439 }
1440
1441 /**
1442 * gnutls_pkcs11_copy_x509_privkey:
1443 * @token_url: A PKCS #11 URL specifying a token
1444 * @key: A private key
1445 * @label: A name to be used for the stored data
1446 * @key_usage: One of GNUTLS_KEY_*
1447 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1448 *
1449 * This function will copy a private key into a PKCS #11 token specified by
1450 * a URL.
1451 *
1452 * Since 3.6.3 the objects are marked as sensitive by default unless
1453 * %GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_SENSITIVE is specified.
1454 *
1455 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1456 * negative error value.
1457 *
1458 * Since: 2.12.0
1459 **/
1460 int gnutls_pkcs11_copy_x509_privkey(const char *token_url,
1461 gnutls_x509_privkey_t key,
1462 const char *label,
1463 unsigned int key_usage, unsigned int flags)
1464 {
1465 int x;
1466 }
1467
1468 #endif
1469