LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib - pkcs11_write.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 568 801 70.9 %
Date: 2020-10-30 04:50:48 Functions: 10 12 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      37         122 : static void mark_flags(unsigned flags, struct ck_attribute *a, unsigned *a_val, unsigned trusted)
      38             : {
      39         122 :         static const unsigned long category = 2;
      40             : 
      41         122 :         if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_CA) {
      42          92 :                 a[*a_val].type = CKA_CERTIFICATE_CATEGORY;
      43          92 :                 a[*a_val].value = (void *) &category;
      44          92 :                 a[*a_val].value_len = sizeof(category);
      45          92 :                 (*a_val)++;
      46             :         }
      47             : 
      48         122 :         if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_DISTRUSTED) {
      49           0 :                 if (trusted) {
      50           0 :                         a[*a_val].type = CKA_X_DISTRUSTED;
      51           0 :                         a[*a_val].value = (void *) &tval;
      52           0 :                         a[*a_val].value_len = sizeof(tval);
      53           0 :                         (*a_val)++;
      54             :                 } else {
      55           0 :                         _gnutls_debug_log("p11: ignoring the distrusted flag as it is not valid on non-p11-kit-trust modules\n");
      56             :                 }
      57             :         }
      58             : 
      59         122 :         if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED) {
      60          96 :                 a[*a_val].type = CKA_TRUSTED;
      61          96 :                 a[*a_val].value = (void *) &tval;
      62          96 :                 a[*a_val].value_len = sizeof(tval);
      63          96 :                 (*a_val)++;
      64             : 
      65          96 :                 a[*a_val].type = CKA_PRIVATE;
      66          96 :                 a[*a_val].value = (void *) &fval;
      67          96 :                 a[*a_val].value_len = sizeof(fval);
      68          96 :                 (*a_val)++;
      69             :         } else {
      70          26 :                 if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE) {
      71          17 :                         a[*a_val].type = CKA_PRIVATE;
      72          17 :                         a[*a_val].value = (void *) &tval;
      73          17 :                         a[*a_val].value_len = sizeof(tval);
      74          17 :                         (*a_val)++;
      75           9 :                 } else if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE) {
      76           7 :                         a[*a_val].type = CKA_PRIVATE;
      77           7 :                         a[*a_val].value = (void *) &fval;
      78           7 :                         a[*a_val].value_len = sizeof(fval);
      79           7 :                         (*a_val)++;
      80             :                 }
      81             :         }
      82         122 : }
      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
     103         119 : 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         119 :         int ret;
     109         119 :         struct p11_kit_uri *info = NULL;
     110         119 :         ck_rv_t rv;
     111         119 :         size_t der_size, id_size, serial_size;
     112         119 :         gnutls_datum_t serial_der = {NULL, 0};
     113         119 :         uint8_t *der = NULL;
     114         119 :         uint8_t serial[128];
     115         119 :         uint8_t id[20];
     116         119 :         struct ck_attribute a[MAX_ASIZE];
     117         119 :         ck_object_class_t class = CKO_CERTIFICATE;
     118         119 :         ck_certificate_type_t type = CKC_X_509;
     119         119 :         ck_object_handle_t ctx;
     120         119 :         unsigned a_val;
     121         119 :         struct pkcs11_session_info sinfo;
     122             :         
     123         119 :         PKCS11_CHECK_INIT;
     124             : 
     125         119 :         ret = pkcs11_url_to_info(token_url, &info, 0);
     126         119 :         if (ret < 0) {
     127           0 :                 gnutls_assert();
     128           0 :                 return ret;
     129             :         }
     130             : 
     131         119 :         ret =
     132         119 :             pkcs11_open_session(&sinfo, NULL, info,
     133             :                                 SESSION_WRITE |
     134         119 :                                 pkcs11_obj_flags_to_int(flags));
     135         119 :         p11_kit_uri_free(info);
     136             : 
     137         119 :         if (ret < 0) {
     138           0 :                 gnutls_assert();
     139           0 :                 return ret;
     140             :         }
     141             : 
     142         119 :         der_size = 0;
     143         119 :         ret =
     144         119 :             gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_DER, NULL,
     145             :                                    &der_size);
     146         119 :         if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
     147           0 :                 gnutls_assert();
     148           0 :                 goto cleanup;
     149             :         }
     150             : 
     151         119 :         der = gnutls_malloc(der_size);
     152         119 :         if (der == NULL) {
     153           0 :                 gnutls_assert();
     154           0 :                 ret = GNUTLS_E_MEMORY_ERROR;
     155           0 :                 goto cleanup;
     156             :         }
     157             : 
     158         119 :         ret =
     159         119 :             gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_DER, der,
     160             :                                    &der_size);
     161         119 :         if (ret < 0) {
     162           0 :                 gnutls_assert();
     163           0 :                 goto cleanup;
     164             :         }
     165             : 
     166         119 :         a[0].type = CKA_CLASS;
     167         119 :         a[0].value = &class;
     168         119 :         a[0].value_len = sizeof(class);
     169             : 
     170         119 :         a[1].type = CKA_ID;
     171         119 :         if (cid == NULL || cid->size == 0) {
     172         115 :                 id_size = sizeof(id);
     173         115 :                 ret = gnutls_x509_crt_get_subject_key_id(crt, id, &id_size, NULL);
     174         115 :                 if (ret < 0) {
     175          28 :                         id_size = sizeof(id);
     176          28 :                         ret = gnutls_x509_crt_get_key_id(crt, 0, id, &id_size);
     177          28 :                         if (ret < 0) {
     178           0 :                           gnutls_assert();
     179           0 :                           goto cleanup;
     180             :                         }
     181             :                 }
     182             : 
     183         115 :                 a[1].value = id;
     184         115 :                 a[1].value_len = id_size;
     185             :         } else {
     186           4 :                 a[1].value = cid->data;
     187           4 :                 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         119 :         a[2].type = CKA_VALUE;
     193         119 :         a[2].value = der;
     194         119 :         a[2].value_len = der_size;
     195         119 :         a[3].type = CKA_TOKEN;
     196         119 :         a[3].value = (void *) &tval;
     197         119 :         a[3].value_len = sizeof(tval);
     198         119 :         a[4].type = CKA_CERTIFICATE_TYPE;
     199         119 :         a[4].value = &type;
     200         119 :         a[4].value_len = sizeof(type);
     201             : 
     202         119 :         a_val = 5;
     203             : 
     204         119 :         a[a_val].type = CKA_SUBJECT;
     205         119 :         a[a_val].value = crt->raw_dn.data;
     206         119 :         a[a_val].value_len = crt->raw_dn.size;
     207         119 :         a_val++;
     208             : 
     209         119 :         if (crt->raw_issuer_dn.size > 0) {
     210         119 :                 a[a_val].type = CKA_ISSUER;
     211         119 :                 a[a_val].value = crt->raw_issuer_dn.data;
     212         119 :                 a[a_val].value_len = crt->raw_issuer_dn.size;
     213         119 :                 a_val++;
     214             :         }
     215             : 
     216         119 :         serial_size = sizeof(serial);
     217         119 :         if (gnutls_x509_crt_get_serial(crt, serial, &serial_size) >= 0) {
     218         119 :                 ret = _gnutls_x509_ext_gen_number(serial, serial_size, &serial_der);
     219         119 :                 if (ret >= 0) {
     220         119 :                         a[a_val].type = CKA_SERIAL_NUMBER;
     221         119 :                         a[a_val].value = (void *) serial_der.data;
     222         119 :                         a[a_val].value_len = serial_der.size;
     223         119 :                         a_val++;
     224             :                 }
     225             :         }
     226             : 
     227         119 :         if (label) {
     228         119 :                 a[a_val].type = CKA_LABEL;
     229         119 :                 a[a_val].value = (void *) label;
     230         119 :                 a[a_val].value_len = strlen(label);
     231         119 :                 a_val++;
     232             :         }
     233             : 
     234         119 :         mark_flags(flags, a, &a_val, sinfo.trusted);
     235             : 
     236         119 :         rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_val, &ctx);
     237         119 :         if (rv != CKR_OK) {
     238           1 :                 gnutls_assert();
     239           1 :                 _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
     240           1 :                 ret = pkcs11_rv_to_err(rv);
     241           1 :                 goto cleanup;
     242             :         }
     243             : 
     244             :         /* generated! 
     245             :          */
     246             : 
     247             :         ret = 0;
     248             : 
     249         119 :       cleanup:
     250         119 :         gnutls_free(der);
     251         119 :         gnutls_free(serial_der.data);
     252         119 :         pkcs11_close_session(&sinfo);
     253         119 :         return ret;
     254             : 
     255             : }
     256             : 
     257           3 : static void clean_pubkey(struct ck_attribute *a, unsigned a_val)
     258             : {
     259           3 :         unsigned i;
     260             : 
     261          29 :         for (i=0;i<a_val;i++) {
     262          26 :                 switch(a[i].type) {
     263           6 :                         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           6 :                                 gnutls_free(a[i].value);
     272           6 :                                 break;
     273             :                 }
     274          26 :         }
     275           3 : }
     276             : 
     277           3 : static int add_pubkey(gnutls_pubkey_t pubkey, struct ck_attribute *a, unsigned *a_val)
     278             : {
     279           3 :         gnutls_pk_algorithm_t pk;
     280           3 :         int ret;
     281             : 
     282           3 :         pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL);
     283             : 
     284           3 :         switch (pk) {
     285           1 :         case GNUTLS_PK_RSA_PSS:
     286             :         case GNUTLS_PK_RSA: {
     287           1 :                 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           1 :                 ret = gnutls_pubkey_export_rsa_raw2(pubkey, &m, &e, GNUTLS_EXPORT_FLAG_NO_LZ);
     293           1 :                 if (ret < 0) {
     294           0 :                         gnutls_assert();
     295           0 :                         return ret;
     296             :                 }
     297             : 
     298             : 
     299           1 :                 a[*a_val].type = CKA_MODULUS;
     300           1 :                 a[*a_val].value = m.data;
     301           1 :                 a[*a_val].value_len = m.size;
     302           1 :                 (*a_val)++;
     303             : 
     304           1 :                 a[*a_val].type = CKA_PUBLIC_EXPONENT;
     305           1 :                 a[*a_val].value = e.data;
     306           1 :                 a[*a_val].value_len = e.size;
     307           1 :                 (*a_val)++;
     308           1 :                 break;
     309             :         }
     310           0 :         case GNUTLS_PK_DSA: {
     311           0 :                 gnutls_datum_t p, q, g, y;
     312             : 
     313           0 :                 ret = gnutls_pubkey_export_dsa_raw2(pubkey, &p, &q, &g, &y, GNUTLS_EXPORT_FLAG_NO_LZ);
     314           0 :                 if (ret < 0) {
     315           0 :                         gnutls_assert();
     316           0 :                         return ret;
     317             :                 }
     318             : 
     319           0 :                 a[*a_val].type = CKA_PRIME;
     320           0 :                 a[*a_val].value = p.data;
     321           0 :                 a[*a_val].value_len = p.size;
     322           0 :                 (*a_val)++;
     323             : 
     324           0 :                 a[*a_val].type = CKA_SUBPRIME;
     325           0 :                 a[*a_val].value = q.data;
     326           0 :                 a[*a_val].value_len = q.size;
     327           0 :                 (*a_val)++;
     328             : 
     329           0 :                 a[*a_val].type = CKA_BASE;
     330           0 :                 a[*a_val].value = g.data;
     331           0 :                 a[*a_val].value_len = g.size;
     332           0 :                 (*a_val)++;
     333             : 
     334           0 :                 a[*a_val].type = CKA_VALUE;
     335           0 :                 a[*a_val].value = y.data;
     336           0 :                 a[*a_val].value_len = y.size;
     337           0 :                 (*a_val)++;
     338           0 :                 break;
     339             :         }
     340           1 :         case GNUTLS_PK_EC: {
     341           1 :                 gnutls_datum_t params, point;
     342             : 
     343           1 :                 ret = gnutls_pubkey_export_ecc_x962(pubkey, &params, &point);
     344           1 :                 if (ret < 0) {
     345           0 :                         gnutls_assert();
     346           0 :                         return ret;
     347             :                 }
     348             : 
     349           1 :                 a[*a_val].type = CKA_EC_PARAMS;
     350           1 :                 a[*a_val].value = params.data;
     351           1 :                 a[*a_val].value_len = params.size;
     352           1 :                 (*a_val)++;
     353             : 
     354           1 :                 a[*a_val].type = CKA_EC_POINT;
     355           1 :                 a[*a_val].value = point.data;
     356           1 :                 a[*a_val].value_len = point.size;
     357           1 :                 (*a_val)++;
     358           1 :                 break;
     359             :         }
     360           1 :         case GNUTLS_PK_EDDSA_ED25519: {
     361           1 :                 gnutls_datum_t params, ecpoint;
     362             : 
     363           1 :                 ret =
     364           1 :                     _gnutls_x509_write_ecc_params(pubkey->params.curve,
     365             :                                                   &params);
     366           1 :                 if (ret < 0) {
     367           0 :                         gnutls_assert();
     368           0 :                         return ret;
     369             :                 }
     370             : 
     371           1 :                 a[*a_val].type = CKA_EC_PARAMS;
     372           1 :                 a[*a_val].value = params.data;
     373           1 :                 a[*a_val].value_len = params.size;
     374           1 :                 (*a_val)++;
     375             : 
     376           2 :                 ret = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING,
     377           1 :                                                  pubkey->params.raw_pub.data,
     378           1 :                                                  pubkey->params.raw_pub.size,
     379             :                                                  &ecpoint);
     380           1 :                 if (ret < 0) {
     381           0 :                         gnutls_assert();
     382           0 :                         return ret;
     383             :                 }
     384             : 
     385           1 :                 a[*a_val].type = CKA_EC_POINT;
     386           1 :                 a[*a_val].value = ecpoint.data;
     387           1 :                 a[*a_val].value_len = ecpoint.size;
     388           1 :                 (*a_val)++;
     389           1 :                 break;
     390             :         }
     391             : 
     392           0 :         default:
     393           0 :                 _gnutls_debug_log("requested writing public key of unsupported type %u\n", (unsigned)pk);
     394           0 :                 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
     420           3 : 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           3 :         int ret;
     426           3 :         struct p11_kit_uri *info = NULL;
     427           3 :         ck_rv_t rv;
     428           3 :         size_t id_size;
     429           3 :         uint8_t id[20];
     430           3 :         struct ck_attribute a[MAX_ASIZE];
     431           3 :         gnutls_pk_algorithm_t pk;
     432           3 :         ck_object_class_t class = CKO_PUBLIC_KEY;
     433           3 :         ck_object_handle_t ctx;
     434           3 :         unsigned a_val;
     435           3 :         ck_key_type_t type;
     436           3 :         struct pkcs11_session_info sinfo;
     437             :         
     438           3 :         PKCS11_CHECK_INIT;
     439             : 
     440           3 :         ret = pkcs11_url_to_info(token_url, &info, 0);
     441           3 :         if (ret < 0) {
     442           0 :                 gnutls_assert();
     443           0 :                 return ret;
     444             :         }
     445             : 
     446           3 :         ret =
     447           3 :             pkcs11_open_session(&sinfo, NULL, info,
     448             :                                 SESSION_WRITE |
     449           3 :                                 pkcs11_obj_flags_to_int(flags));
     450           3 :         p11_kit_uri_free(info);
     451             : 
     452           3 :         if (ret < 0) {
     453           0 :                 gnutls_assert();
     454           0 :                 return ret;
     455             :         }
     456             : 
     457           3 :         a[0].type = CKA_CLASS;
     458           3 :         a[0].value = &class;
     459           3 :         a[0].value_len = sizeof(class);
     460             : 
     461           3 :         a[1].type = CKA_TOKEN;
     462           3 :         a[1].value = (void *) &tval;
     463           3 :         a[1].value_len = sizeof(tval);
     464             : 
     465           3 :         a_val = 2;
     466             : 
     467           3 :         ret = add_pubkey(pubkey, a, &a_val);
     468           3 :         if (ret < 0) {
     469           0 :                 gnutls_assert();
     470           0 :                 goto cleanup;
     471             :         }
     472             : 
     473           3 :         if (label) {
     474           3 :                 a[a_val].type = CKA_LABEL;
     475           3 :                 a[a_val].value = (void *) label;
     476           3 :                 a[a_val].value_len = strlen(label);
     477           3 :                 a_val++;
     478             :         }
     479             : 
     480           3 :         pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL);
     481           3 :         type = pk_to_key_type(pk);
     482           3 :         FIX_KEY_USAGE(pk, key_usage);
     483             : 
     484           3 :         a[a_val].type = CKA_KEY_TYPE;
     485           3 :         a[a_val].value = &type;
     486           3 :         a[a_val].value_len = sizeof(type);
     487           3 :         a_val++;
     488             : 
     489           3 :         a[a_val].type = CKA_ID;
     490           3 :         if (cid == NULL || cid->size == 0) {
     491           3 :                 id_size = sizeof(id);
     492           3 :                 ret = gnutls_pubkey_get_key_id(pubkey, 0, id, &id_size);
     493           3 :                 if (ret < 0) {
     494           0 :                           gnutls_assert();
     495           0 :                           goto cleanup;
     496             :                 }
     497             : 
     498           3 :                 a[a_val].value = id;
     499           3 :                 a[a_val].value_len = id_size;
     500             :         } else {
     501           0 :                 a[a_val].value = cid->data;
     502           0 :                 a[a_val].value_len = cid->size;
     503             :         }
     504           3 :         a_val++;
     505             : 
     506           3 :         mark_flags(flags, a, &a_val, sinfo.trusted);
     507             : 
     508           3 :         a[a_val].type = CKA_VERIFY;
     509           3 :         if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE) {
     510           3 :                 a[a_val].value = (void*)&tval;
     511           3 :                 a[a_val].value_len = sizeof(tval);
     512             :         } else {
     513           0 :                 a[a_val].value = (void*)&fval;
     514           0 :                 a[a_val].value_len = sizeof(fval);
     515             :         }
     516           3 :         a_val++;
     517             : 
     518           3 :         if (pk == GNUTLS_PK_RSA) {
     519           1 :                 a[a_val].type = CKA_ENCRYPT;
     520           1 :                 if (key_usage & (GNUTLS_KEY_ENCIPHER_ONLY|GNUTLS_KEY_DECIPHER_ONLY)) {
     521           1 :                         a[a_val].value = (void*)&tval;
     522           1 :                         a[a_val].value_len = sizeof(tval);
     523             :                 } else {
     524           0 :                         a[a_val].value = (void*)&fval;
     525           0 :                         a[a_val].value_len = sizeof(fval);
     526             :                 }
     527           1 :                 a_val++;
     528             :         }
     529             : 
     530           3 :         rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_val, &ctx);
     531           3 :         if (rv != CKR_OK) {
     532           0 :                 gnutls_assert();
     533           0 :                 _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
     534           0 :                 ret = pkcs11_rv_to_err(rv);
     535           0 :                 goto cleanup;
     536             :         }
     537             : 
     538             :         /* generated! 
     539             :          */
     540             : 
     541             :         ret = 0;
     542             : 
     543           3 :       cleanup:
     544           3 :         clean_pubkey(a, a_val);
     545           3 :         pkcs11_close_session(&sinfo);
     546           3 :         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
     570           0 : 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           0 :         int ret;
     577           0 :         struct p11_kit_uri *info = NULL;
     578           0 :         ck_rv_t rv;
     579           0 :         struct ck_attribute a[MAX_ASIZE];
     580           0 :         ck_object_handle_t ctx;
     581           0 :         unsigned a_vals;
     582           0 :         struct pkcs11_session_info sinfo;
     583           0 :         ck_object_class_t class;
     584           0 :         gnutls_datum_t spki = {NULL, 0};
     585             :         
     586           0 :         PKCS11_CHECK_INIT;
     587             : 
     588           0 :         ret = pkcs11_url_to_info(token_url, &info, 0);
     589           0 :         if (ret < 0) {
     590           0 :                 gnutls_assert();
     591           0 :                 return ret;
     592             :         }
     593             : 
     594           0 :         ret =
     595           0 :             pkcs11_open_session(&sinfo, NULL, info,
     596             :                                 SESSION_WRITE |
     597           0 :                                 pkcs11_obj_flags_to_int(flags));
     598           0 :         p11_kit_uri_free(info);
     599             : 
     600           0 :         if (ret < 0) {
     601           0 :                 gnutls_assert();
     602           0 :                 return ret;
     603             :         }
     604             : 
     605           0 :         ret = x509_crt_to_raw_pubkey(crt, &spki);
     606           0 :         if (ret < 0) {
     607           0 :                 gnutls_assert();
     608           0 :                 goto cleanup;
     609             :         }
     610             : 
     611           0 :         class = CKO_X_CERTIFICATE_EXTENSION;
     612           0 :         a_vals = 0;
     613           0 :         a[a_vals].type = CKA_CLASS;
     614           0 :         a[a_vals].value = &class;
     615           0 :         a[a_vals++].value_len = sizeof(class);
     616             : 
     617           0 :         a[a_vals].type = CKA_PUBLIC_KEY_INFO;
     618           0 :         a[a_vals].value = spki.data;
     619           0 :         a[a_vals++].value_len = spki.size;
     620             : 
     621           0 :         a[a_vals].type = CKA_VALUE;
     622           0 :         a[a_vals].value = data->data;
     623           0 :         a[a_vals++].value_len = data->size;
     624             : 
     625           0 :         a[a_vals].type = CKA_TOKEN;
     626           0 :         a[a_vals].value = (void *) &tval;
     627           0 :         a[a_vals++].value_len = sizeof(tval);
     628             : 
     629           0 :         if (label) {
     630           0 :                 a[a_vals].type = CKA_LABEL;
     631           0 :                 a[a_vals].value = (void *) label;
     632           0 :                 a[a_vals++].value_len = strlen(label);
     633             :         }
     634             : 
     635           0 :         rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_vals, &ctx);
     636           0 :         if (rv != CKR_OK) {
     637           0 :                 gnutls_assert();
     638           0 :                 _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
     639           0 :                 ret = pkcs11_rv_to_err(rv);
     640           0 :                 goto cleanup;
     641             :         }
     642             : 
     643             :         ret = 0;
     644             : 
     645           0 :       cleanup:
     646           0 :         pkcs11_close_session(&sinfo);
     647           0 :         gnutls_free(spki.data);
     648           0 :         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
     673          32 : 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          32 :         int ret;
     680          32 :         struct p11_kit_uri *info = NULL;
     681          32 :         ck_rv_t rv;
     682          32 :         size_t id_size;
     683          32 :         uint8_t id[20];
     684          32 :         struct ck_attribute a[32];
     685          32 :         ck_object_class_t class = CKO_PRIVATE_KEY;
     686          32 :         ck_object_handle_t ctx;
     687          32 :         ck_key_type_t type;
     688          32 :         int a_val;
     689          32 :         gnutls_pk_algorithm_t pk;
     690          32 :         gnutls_datum_t p, q, g, y, x;
     691          32 :         gnutls_datum_t m, e, d, u, exp1, exp2;
     692          32 :         struct pkcs11_session_info sinfo;
     693             : 
     694          32 :         PKCS11_CHECK_INIT;
     695             : 
     696          32 :         memset(&p, 0, sizeof(p));
     697          32 :         memset(&q, 0, sizeof(q));
     698          32 :         memset(&g, 0, sizeof(g));
     699          32 :         memset(&y, 0, sizeof(y));
     700          32 :         memset(&x, 0, sizeof(x));
     701          32 :         memset(&m, 0, sizeof(m));
     702          32 :         memset(&e, 0, sizeof(e));
     703          32 :         memset(&d, 0, sizeof(d));
     704          32 :         memset(&u, 0, sizeof(u));
     705          32 :         memset(&exp1, 0, sizeof(exp1));
     706          32 :         memset(&exp2, 0, sizeof(exp2));
     707             : 
     708          32 :         ret = pkcs11_url_to_info(token_url, &info, 0);
     709          32 :         if (ret < 0) {
     710           0 :                 gnutls_assert();
     711           0 :                 return ret;
     712             :         }
     713             : 
     714          32 :         ret =
     715          32 :             pkcs11_open_session(&sinfo, NULL, info,
     716             :                                 SESSION_WRITE |
     717          32 :                                 pkcs11_obj_flags_to_int(flags));
     718          32 :         p11_kit_uri_free(info);
     719             : 
     720          32 :         if (ret < 0) {
     721           0 :                 gnutls_assert();
     722           0 :                 return ret;
     723             :         }
     724             : 
     725          32 :         pk = gnutls_x509_privkey_get_pk_algorithm(key);
     726          32 :         FIX_KEY_USAGE(pk, key_usage);
     727             : 
     728          32 :         a_val = 0;
     729          32 :         a[a_val].type = CKA_CLASS;
     730          32 :         a[a_val].value = &class;
     731          32 :         a[a_val].value_len = sizeof(class);
     732          32 :         a_val++;
     733             : 
     734          32 :         a[a_val].type = CKA_ID;
     735          32 :         if (cid == NULL || cid->size == 0) {
     736          32 :                 id_size = sizeof(id);
     737          32 :                 ret = gnutls_x509_privkey_get_key_id(key, 0, id, &id_size);
     738          32 :                 if (ret < 0) {
     739           0 :                         p11_kit_uri_free(info);
     740           0 :                         gnutls_assert();
     741           0 :                         return ret;
     742             :                 }
     743             : 
     744          32 :                 a[a_val].value = id;
     745          32 :                 a[a_val].value_len = id_size;
     746             :         } else {
     747           0 :                 a[a_val].value = cid->data;
     748           0 :                 a[a_val].value_len = cid->size;
     749             :         }
     750          32 :         a_val++;
     751             : 
     752          32 :         a[a_val].type = CKA_SIGN;
     753          32 :         if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE) {
     754          30 :                 a[a_val].value = (void*)&tval;
     755          30 :                 a[a_val].value_len = sizeof(tval);
     756             :         } else {
     757           2 :                 a[a_val].value = (void*)&fval;
     758           2 :                 a[a_val].value_len = sizeof(fval);
     759             :         }
     760          32 :         a_val++;
     761             : 
     762          32 :         if (pk == GNUTLS_PK_RSA) {
     763          20 :                 a[a_val].type = CKA_DECRYPT;
     764          20 :                 if ((key_usage & (GNUTLS_KEY_ENCIPHER_ONLY|GNUTLS_KEY_DECIPHER_ONLY)) ||
     765             :                     (key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT)) {
     766          12 :                         a[a_val].value = (void*)&tval;
     767          12 :                         a[a_val].value_len = sizeof(tval);
     768             :                 } else {
     769           8 :                         a[a_val].value = (void*)&fval;
     770           8 :                         a[a_val].value_len = sizeof(fval);
     771             :                 }
     772             :                 a_val++;
     773             :         }
     774             : 
     775          32 :         a[a_val].type = CKA_TOKEN;
     776          32 :         a[a_val].value = (void *) &tval;
     777          32 :         a[a_val].value_len = sizeof(tval);
     778          32 :         a_val++;
     779             : 
     780             :         /* a private key is set always as private unless
     781             :          * requested otherwise
     782             :          */
     783          32 :         if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE) {
     784           0 :                 a[a_val].type = CKA_PRIVATE;
     785           0 :                 a[a_val].value = (void *) &fval;
     786           0 :                 a[a_val].value_len = sizeof(fval);
     787           0 :                 a_val++;
     788             :         } else {
     789          32 :                 a[a_val].type = CKA_PRIVATE;
     790          32 :                 a[a_val].value = (void *) &tval;
     791          32 :                 a[a_val].value_len = sizeof(tval);
     792          32 :                 a_val++;
     793             :         }
     794             : 
     795          32 :         if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_ALWAYS_AUTH) {
     796           0 :                 a[a_val].type = CKA_ALWAYS_AUTHENTICATE;
     797           0 :                 a[a_val].value = (void *) &tval;
     798           0 :                 a[a_val].value_len = sizeof(tval);
     799           0 :                 a_val++;
     800             :         }
     801             : 
     802          32 :         if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_EXTRACTABLE) {
     803           0 :                 a[a_val].type = CKA_EXTRACTABLE;
     804           0 :                 a[a_val].value = (void *) &tval;
     805           0 :                 a[a_val].value_len = sizeof(tval);
     806           0 :                 (a_val)++;
     807             :         } else {
     808          32 :                 a[a_val].type = CKA_EXTRACTABLE;
     809          32 :                 a[a_val].value = (void *) &fval;
     810          32 :                 a[a_val].value_len = sizeof(fval);
     811          32 :                 (a_val)++;
     812             :         }
     813             : 
     814          32 :         if (label) {
     815          32 :                 a[a_val].type = CKA_LABEL;
     816          32 :                 a[a_val].value = (void *) label;
     817          32 :                 a[a_val].value_len = strlen(label);
     818          32 :                 a_val++;
     819             :         }
     820             : 
     821          32 :         if (!(flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_SENSITIVE)) {
     822          32 :                 a[a_val].type = CKA_SENSITIVE;
     823          32 :                 a[a_val].value = (void *) &tval;
     824          32 :                 a[a_val].value_len = sizeof(tval);
     825          32 :                 a_val++;
     826             :         } else {
     827           0 :                 a[a_val].type = CKA_SENSITIVE;
     828           0 :                 a[a_val].value = (void *) &fval;
     829           0 :                 a[a_val].value_len = sizeof(fval);
     830           0 :                 a_val++;
     831             :         }
     832             : 
     833          32 :         switch (pk) {
     834          22 :         case GNUTLS_PK_RSA:
     835             :         case GNUTLS_PK_RSA_PSS:
     836             :                 {
     837             : 
     838          22 :                         ret = _gnutls_params_get_rsa_raw(&key->params, &m, &e, &d, &p,
     839             :                                                          &q, &u, &exp1, &exp2,
     840             :                                                          GNUTLS_EXPORT_FLAG_NO_LZ);
     841          22 :                         if (ret < 0) {
     842           0 :                                 gnutls_assert();
     843           0 :                                 goto cleanup;
     844             :                         }
     845             : 
     846          22 :                         type = CKK_RSA;
     847             : 
     848          22 :                         a[a_val].type = CKA_MODULUS;
     849          22 :                         a[a_val].value = m.data;
     850          22 :                         a[a_val].value_len = m.size;
     851          22 :                         a_val++;
     852             : 
     853          22 :                         a[a_val].type = CKA_PUBLIC_EXPONENT;
     854          22 :                         a[a_val].value = e.data;
     855          22 :                         a[a_val].value_len = e.size;
     856          22 :                         a_val++;
     857             : 
     858          22 :                         a[a_val].type = CKA_PRIVATE_EXPONENT;
     859          22 :                         a[a_val].value = d.data;
     860          22 :                         a[a_val].value_len = d.size;
     861          22 :                         a_val++;
     862             : 
     863          22 :                         a[a_val].type = CKA_PRIME_1;
     864          22 :                         a[a_val].value = p.data;
     865          22 :                         a[a_val].value_len = p.size;
     866          22 :                         a_val++;
     867             : 
     868          22 :                         a[a_val].type = CKA_PRIME_2;
     869          22 :                         a[a_val].value = q.data;
     870          22 :                         a[a_val].value_len = q.size;
     871          22 :                         a_val++;
     872             : 
     873          22 :                         a[a_val].type = CKA_COEFFICIENT;
     874          22 :                         a[a_val].value = u.data;
     875          22 :                         a[a_val].value_len = u.size;
     876          22 :                         a_val++;
     877             : 
     878          22 :                         a[a_val].type = CKA_EXPONENT_1;
     879          22 :                         a[a_val].value = exp1.data;
     880          22 :                         a[a_val].value_len = exp1.size;
     881          22 :                         a_val++;
     882             : 
     883          22 :                         a[a_val].type = CKA_EXPONENT_2;
     884          22 :                         a[a_val].value = exp2.data;
     885          22 :                         a[a_val].value_len = exp2.size;
     886          22 :                         a_val++;
     887             : 
     888          22 :                         break;
     889             :                 }
     890           1 :         case GNUTLS_PK_DSA:
     891             :                 {
     892           1 :                         ret = _gnutls_params_get_dsa_raw(&key->params, &p, &q, &g, &y, &x,
     893             :                                                          GNUTLS_EXPORT_FLAG_NO_LZ);
     894           1 :                         if (ret < 0) {
     895           0 :                                 gnutls_assert();
     896           0 :                                 goto cleanup;
     897             :                         }
     898             : 
     899           1 :                         type = CKK_DSA;
     900             : 
     901           1 :                         a[a_val].type = CKA_PRIME;
     902           1 :                         a[a_val].value = p.data;
     903           1 :                         a[a_val].value_len = p.size;
     904           1 :                         a_val++;
     905             : 
     906           1 :                         a[a_val].type = CKA_SUBPRIME;
     907           1 :                         a[a_val].value = q.data;
     908           1 :                         a[a_val].value_len = q.size;
     909           1 :                         a_val++;
     910             : 
     911           1 :                         a[a_val].type = CKA_BASE;
     912           1 :                         a[a_val].value = g.data;
     913           1 :                         a[a_val].value_len = g.size;
     914           1 :                         a_val++;
     915             : 
     916           1 :                         a[a_val].type = CKA_VALUE;
     917           1 :                         a[a_val].value = x.data;
     918           1 :                         a[a_val].value_len = x.size;
     919           1 :                         a_val++;
     920             : 
     921           1 :                         break;
     922             :                 }
     923           6 :         case GNUTLS_PK_EC:
     924             :                 {
     925           6 :                         ret =
     926           6 :                             _gnutls_x509_write_ecc_params(key->params.curve,
     927             :                                                           &p);
     928           6 :                         if (ret < 0) {
     929           0 :                                 gnutls_assert();
     930           0 :                                 goto cleanup;
     931             :                         }
     932             : 
     933           6 :                         ret =
     934           6 :                             _gnutls_mpi_dprint(key->params.
     935             :                                                 params[ECC_K], &x);
     936           6 :                         if (ret < 0) {
     937           0 :                                 gnutls_assert();
     938           0 :                                 goto cleanup;
     939             :                         }
     940             : 
     941           6 :                         type = CKK_ECDSA;
     942             : 
     943           6 :                         a[a_val].type = CKA_EC_PARAMS;
     944           6 :                         a[a_val].value = p.data;
     945           6 :                         a[a_val].value_len = p.size;
     946           6 :                         a_val++;
     947             : 
     948           6 :                         a[a_val].type = CKA_VALUE;
     949           6 :                         a[a_val].value = x.data;
     950           6 :                         a[a_val].value_len = x.size;
     951           6 :                         a_val++;
     952             : 
     953           6 :                         break;
     954             :                 }
     955             : #ifdef HAVE_CKM_EDDSA
     956           3 :         case GNUTLS_PK_EDDSA_ED25519:
     957             :                 {
     958           3 :                         ret =
     959           3 :                             _gnutls_x509_write_ecc_params(key->params.curve,
     960             :                                                           &p);
     961           3 :                         if (ret < 0) {
     962           0 :                                 gnutls_assert();
     963           0 :                                 goto cleanup;
     964             :                         }
     965             : 
     966           3 :                         type = CKK_EC_EDWARDS;
     967             : 
     968           3 :                         a[a_val].type = CKA_EC_PARAMS;
     969           3 :                         a[a_val].value = p.data;
     970           3 :                         a[a_val].value_len = p.size;
     971           3 :                         a_val++;
     972             : 
     973           3 :                         a[a_val].type = CKA_VALUE;
     974           3 :                         a[a_val].value = key->params.raw_priv.data;
     975           3 :                         a[a_val].value_len = key->params.raw_priv.size;
     976           3 :                         a_val++;
     977             : 
     978           3 :                         break;
     979             :                 }
     980             : #endif
     981           0 :         default:
     982           0 :                 gnutls_assert();
     983           0 :                 ret = GNUTLS_E_INVALID_REQUEST;
     984           0 :                 goto cleanup;
     985             :         }
     986             : 
     987          32 :         a[a_val].type = CKA_KEY_TYPE;
     988          32 :         a[a_val].value = &type;
     989          32 :         a[a_val].value_len = sizeof(type);
     990          32 :         a_val++;
     991             : 
     992          32 :         rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_val, &ctx);
     993          32 :         if (rv != CKR_OK) {
     994           0 :                 gnutls_assert();
     995           0 :                 _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
     996           0 :                 ret = pkcs11_rv_to_err(rv);
     997           0 :                 goto cleanup;
     998             :         }
     999             : 
    1000             :         ret = 0;
    1001             : 
    1002          32 :       cleanup:
    1003          32 :         switch (pk) {
    1004          22 :         case GNUTLS_PK_RSA_PSS:
    1005             :         case GNUTLS_PK_RSA:
    1006             :                 {
    1007          22 :                         gnutls_free(m.data);
    1008          22 :                         gnutls_free(e.data);
    1009          22 :                         gnutls_free(d.data);
    1010          22 :                         gnutls_free(p.data);
    1011          22 :                         gnutls_free(q.data);
    1012          22 :                         gnutls_free(u.data);
    1013          22 :                         gnutls_free(exp1.data);
    1014          22 :                         gnutls_free(exp2.data);
    1015          22 :                         break;
    1016             :                 }
    1017           1 :         case GNUTLS_PK_DSA:
    1018             :                 {
    1019           1 :                         gnutls_free(p.data);
    1020           1 :                         gnutls_free(q.data);
    1021           1 :                         gnutls_free(g.data);
    1022           1 :                         gnutls_free(y.data);
    1023           1 :                         gnutls_free(x.data);
    1024           1 :                         break;
    1025             :                 }
    1026           9 :         case GNUTLS_PK_EC:
    1027             :         case GNUTLS_PK_EDDSA_ED25519:
    1028             :                 {
    1029           9 :                         gnutls_free(p.data);
    1030           9 :                         gnutls_free(x.data);
    1031           9 :                         break;
    1032             :                 }
    1033           0 :         default:
    1034           0 :                 gnutls_assert();
    1035             :                 ret = GNUTLS_E_INVALID_REQUEST;
    1036             :                 break;
    1037             :         }
    1038             : 
    1039          32 :         if (sinfo.pks != 0)
    1040          32 :                 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
    1052          25 : 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          25 :         struct delete_data_st *find_data = input;
    1057          25 :         struct ck_attribute a[4];
    1058          25 :         struct ck_attribute *attr;
    1059          25 :         ck_object_class_t class;
    1060          25 :         ck_certificate_type_t type = (ck_certificate_type_t) - 1;
    1061          25 :         ck_rv_t rv;
    1062          25 :         ck_object_handle_t ctx;
    1063          25 :         unsigned long count, a_vals;
    1064          25 :         int found = 0, ret;
    1065             : 
    1066          25 :         if (tinfo == NULL) {    /* we don't support multiple calls */
    1067           0 :                 gnutls_assert();
    1068           0 :                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
    1069             :         }
    1070             : 
    1071             :         /* do not bother reading the token if basic fields do not match
    1072             :          */
    1073          50 :         if (!p11_kit_uri_match_module_info(find_data->info, lib_info) ||
    1074          25 :             !p11_kit_uri_match_token_info(find_data->info, tinfo)) {
    1075           0 :                 gnutls_assert();
    1076           0 :                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
    1077             :         }
    1078             : 
    1079             :         /* Find objects with given class and type */
    1080          25 :         class = CKO_CERTIFICATE;        /* default  */
    1081          25 :         a_vals = 0;
    1082             : 
    1083          25 :         attr = p11_kit_uri_get_attribute(find_data->info, CKA_CLASS);
    1084          25 :         if (attr != NULL) {
    1085           9 :                 if (attr->value
    1086           9 :                     && attr->value_len == sizeof(ck_object_class_t))
    1087           9 :                         class = *((ck_object_class_t *) attr->value);
    1088           9 :                 if (class == CKO_CERTIFICATE)
    1089           1 :                         type = CKC_X_509;
    1090             : 
    1091           9 :                 a[a_vals].type = CKA_CLASS;
    1092           9 :                 a[a_vals].value = &class;
    1093           9 :                 a[a_vals].value_len = sizeof(class);
    1094           9 :                 a_vals++;
    1095             :         }
    1096             : 
    1097          25 :         attr = p11_kit_uri_get_attribute(find_data->info, CKA_ID);
    1098          25 :         if (attr != NULL) {
    1099           0 :                 memcpy(a + a_vals, attr, sizeof(struct ck_attribute));
    1100           0 :                 a_vals++;
    1101             :         }
    1102             : 
    1103          25 :         if (type != (ck_certificate_type_t) - 1) {
    1104           1 :                 a[a_vals].type = CKA_CERTIFICATE_TYPE;
    1105           1 :                 a[a_vals].value = &type;
    1106           1 :                 a[a_vals].value_len = sizeof type;
    1107           1 :                 a_vals++;
    1108             :         }
    1109             : 
    1110          25 :         attr = p11_kit_uri_get_attribute(find_data->info, CKA_LABEL);
    1111          25 :         if (attr != NULL) {
    1112          25 :                 memcpy(a + a_vals, attr, sizeof(struct ck_attribute));
    1113          25 :                 a_vals++;
    1114             :         }
    1115             : 
    1116          25 :         rv = pkcs11_find_objects_init(sinfo->module, sinfo->pks, a,
    1117             :                                       a_vals);
    1118          25 :         if (rv != CKR_OK) {
    1119           0 :                 gnutls_assert();
    1120           0 :                 _gnutls_debug_log("p11: FindObjectsInit failed.\n");
    1121           0 :                 ret = pkcs11_rv_to_err(rv);
    1122           0 :                 goto cleanup;
    1123             :         }
    1124             : 
    1125          50 :         while (pkcs11_find_objects
    1126             :                (sinfo->module, sinfo->pks, &ctx, 1, &count) == CKR_OK
    1127          50 :                && count == 1) {
    1128          25 :                 rv = pkcs11_destroy_object(sinfo->module, sinfo->pks, ctx);
    1129          25 :                 if (rv != CKR_OK) {
    1130           0 :                         _gnutls_debug_log
    1131             :                             ("p11: Cannot destroy object: %s\n",
    1132             :                              pkcs11_strerror(rv));
    1133             :                 } else {
    1134          25 :                         find_data->deleted++;
    1135             :                 }
    1136             : 
    1137             :                 found = 1;
    1138             :         }
    1139             : 
    1140          25 :         if (found == 0) {
    1141           0 :                 gnutls_assert();
    1142             :                 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
    1143             :         } else {
    1144             :                 ret = 0;
    1145             :         }
    1146             : 
    1147          25 :       cleanup:
    1148          25 :         pkcs11_find_objects_final(sinfo);
    1149             : 
    1150          25 :         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             :  **/
    1167          25 : int gnutls_pkcs11_delete_url(const char *object_url, unsigned int flags)
    1168             : {
    1169          25 :         int ret;
    1170          25 :         struct delete_data_st find_data;
    1171             : 
    1172          25 :         PKCS11_CHECK_INIT;
    1173             : 
    1174          25 :         memset(&find_data, 0, sizeof(find_data));
    1175             : 
    1176          25 :         ret = pkcs11_url_to_info(object_url, &find_data.info, 0);
    1177          25 :         if (ret < 0) {
    1178           0 :                 gnutls_assert();
    1179           0 :                 return ret;
    1180             :         }
    1181             : 
    1182          25 :         ret =
    1183          25 :             _pkcs11_traverse_tokens(delete_obj_url_cb, &find_data,
    1184             :                                     find_data.info, NULL,
    1185             :                                     SESSION_WRITE |
    1186          25 :                                     pkcs11_obj_flags_to_int(flags));
    1187          25 :         p11_kit_uri_free(find_data.info);
    1188             : 
    1189          25 :         if (ret < 0) {
    1190           0 :                 gnutls_assert();
    1191           0 :                 return ret;
    1192             :         }
    1193             : 
    1194          25 :         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
    1212         100 : gnutls_pkcs11_token_init(const char *token_url,
    1213             :                          const char *so_pin, const char *label)
    1214             : {
    1215         100 :         int ret;
    1216         100 :         struct p11_kit_uri *info = NULL;
    1217         100 :         ck_rv_t rv;
    1218         100 :         struct ck_function_list *module;
    1219         100 :         ck_slot_id_t slot;
    1220         100 :         char flabel[32];
    1221             : 
    1222         100 :         PKCS11_CHECK_INIT;
    1223             : 
    1224         100 :         ret = pkcs11_url_to_info(token_url, &info, 0);
    1225         100 :         if (ret < 0) {
    1226           0 :                 gnutls_assert();
    1227           0 :                 return ret;
    1228             :         }
    1229             : 
    1230         100 :         ret = pkcs11_find_slot(&module, &slot, info, NULL, NULL, NULL);
    1231         100 :         p11_kit_uri_free(info);
    1232             : 
    1233         100 :         if (ret < 0) {
    1234           0 :                 gnutls_assert();
    1235           0 :                 return ret;
    1236             :         }
    1237             : 
    1238             :         /* so it seems memset has other uses than zeroing! */
    1239         100 :         memset(flabel, ' ', sizeof(flabel));
    1240         100 :         if (label != NULL)
    1241         100 :                 memcpy(flabel, label, strlen(label));
    1242             : 
    1243         100 :         rv = pkcs11_init_token(module, slot, (uint8_t *) so_pin,
    1244             :                                strlen(so_pin), (uint8_t *) flabel);
    1245         100 :         if (rv != CKR_OK) {
    1246           0 :                 gnutls_assert();
    1247           0 :                 _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
    1248           0 :                 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
    1274          19 : gnutls_pkcs11_token_set_pin(const char *token_url,
    1275             :                             const char *oldpin,
    1276             :                             const char *newpin, unsigned int flags)
    1277             : {
    1278          19 :         int ret;
    1279          19 :         struct p11_kit_uri *info = NULL;
    1280          19 :         ck_rv_t rv;
    1281          19 :         unsigned int ses_flags;
    1282          19 :         struct pkcs11_session_info sinfo;
    1283             : 
    1284          19 :         PKCS11_CHECK_INIT;
    1285             : 
    1286          19 :         ret = pkcs11_url_to_info(token_url, &info, 0);
    1287          19 :         if (ret < 0) {
    1288           0 :                 gnutls_assert();
    1289           0 :                 return ret;
    1290             :         }
    1291             : 
    1292          19 :         if (((flags & GNUTLS_PIN_USER) && oldpin == NULL) ||
    1293           4 :             (flags & GNUTLS_PIN_SO))
    1294             :                 ses_flags = SESSION_WRITE | SESSION_LOGIN | SESSION_SO;
    1295             :         else
    1296           0 :                 ses_flags = SESSION_WRITE | SESSION_LOGIN;
    1297             : 
    1298          19 :         ret = pkcs11_open_session(&sinfo, NULL, info, ses_flags);
    1299          19 :         p11_kit_uri_free(info);
    1300             : 
    1301          19 :         if (ret < 0) {
    1302           0 :                 gnutls_assert();
    1303           0 :                 return ret;
    1304             :         }
    1305             : 
    1306          19 :         if (oldpin == NULL && !(flags & GNUTLS_PIN_SO)) {
    1307             :                 /* This changes only the user PIN */
    1308          15 :                 rv = pkcs11_init_pin(sinfo.module, sinfo.pks,
    1309             :                                      (uint8_t *) newpin, strlen(newpin));
    1310          15 :                 if (rv != CKR_OK) {
    1311           0 :                         gnutls_assert();
    1312           0 :                         _gnutls_debug_log("p11: %s\n",
    1313             :                                           pkcs11_strerror(rv));
    1314           0 :                         ret = pkcs11_rv_to_err(rv);
    1315           0 :                         goto finish;
    1316             :                 }
    1317             :         } else {
    1318           4 :                 struct p11_kit_pin *pin;
    1319           4 :                 unsigned oldpin_size;
    1320             : 
    1321           4 :                 oldpin_size = L(oldpin);
    1322             : 
    1323           4 :                 if (!(sinfo.tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
    1324           4 :                         if (newpin == NULL)
    1325           0 :                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1326             : 
    1327           4 :                         if (oldpin == NULL) {
    1328           4 :                                 struct pin_info_st pin_info;
    1329           4 :                                 memset(&pin_info, 0, sizeof(pin_info));
    1330             : 
    1331           4 :                                 ret = pkcs11_retrieve_pin(&pin_info, info, &sinfo.tinfo, 0, CKU_SO, &pin);
    1332           4 :                                 if (ret < 0) {
    1333           0 :                                         gnutls_assert();
    1334           0 :                                         goto finish;
    1335             :                                 }
    1336           4 :                                 oldpin = (const char*)p11_kit_pin_get_value(pin, NULL);
    1337           4 :                                 oldpin_size = p11_kit_pin_get_length(pin);
    1338             :                         }
    1339             :                 }
    1340             : 
    1341           8 :                 rv = pkcs11_set_pin(sinfo.module, sinfo.pks,
    1342             :                                     oldpin, oldpin_size,
    1343           4 :                                     newpin, L(newpin));
    1344           4 :                 if (rv != CKR_OK) {
    1345           0 :                         gnutls_assert();
    1346           0 :                         _gnutls_debug_log("p11: %s\n",
    1347             :                                           pkcs11_strerror(rv));
    1348           0 :                         ret = pkcs11_rv_to_err(rv);
    1349           0 :                         goto finish;
    1350             :                 }
    1351             :         }
    1352             : 
    1353             :         ret = 0;
    1354             : 
    1355          19 :       finish:
    1356          19 :         pkcs11_close_session(&sinfo);
    1357          19 :         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
    1375           0 : gnutls_pkcs11_token_get_random(const char *token_url,
    1376             :                                void *rnddata, size_t len)
    1377             : {
    1378           0 :         int ret;
    1379           0 :         struct p11_kit_uri *info = NULL;
    1380           0 :         ck_rv_t rv;
    1381           0 :         struct pkcs11_session_info sinfo;
    1382             : 
    1383           0 :         PKCS11_CHECK_INIT;
    1384             : 
    1385           0 :         ret = pkcs11_url_to_info(token_url, &info, 0);
    1386           0 :         if (ret < 0) {
    1387           0 :                 gnutls_assert();
    1388           0 :                 return ret;
    1389             :         }
    1390             : 
    1391           0 :         ret = pkcs11_open_session(&sinfo, NULL, info, 0);
    1392           0 :         p11_kit_uri_free(info);
    1393             : 
    1394           0 :         if (ret < 0) {
    1395           0 :                 gnutls_assert();
    1396           0 :                 return ret;
    1397             :         }
    1398             : 
    1399           0 :         rv = _gnutls_pkcs11_get_random(sinfo.module, sinfo.pks, rnddata, len);
    1400           0 :         if (rv != CKR_OK) {
    1401           0 :                 gnutls_assert();
    1402           0 :                 _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
    1403           0 :                 ret = pkcs11_rv_to_err(rv);
    1404           0 :                 goto finish;
    1405             :         }
    1406             : 
    1407             :         ret = 0;
    1408             : 
    1409           0 :       finish:
    1410           0 :         pkcs11_close_session(&sinfo);
    1411           0 :         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

Generated by: LCOV version 1.14