LCOV - code coverage report
Current view: top level - pkcs11/gkm - gkm-attributes.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 87.5 % 343 300
Test Date: 2024-04-08 13:24:42 Functions: 97.5 % 40 39

            Line data    Source code
       1              : /*
       2              :  * gnome-keyring
       3              :  *
       4              :  * Copyright (C) 2008 Stefan Walter
       5              :  *
       6              :  * This program is free software; you can redistribute it and/or modify
       7              :  * it under the terms of the GNU Lesser General Public License as
       8              :  * published by the Free Software Foundation; either version 2.1 of
       9              :  * the License, or (at your option) any later version.
      10              :  *
      11              :  * This program is distributed in the hope that it will be useful, but
      12              :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14              :  * Lesser General Public License for more details.
      15              :  *
      16              :  * You should have received a copy of the GNU Lesser General Public
      17              :  * License along with this program; if not, see
      18              :  * <http://www.gnu.org/licenses/>.
      19              :  */
      20              : 
      21              : #include "config.h"
      22              : 
      23              : #include "gkm-attributes.h"
      24              : #include "gkm-data-der.h"
      25              : #include "gkm-util.h"
      26              : 
      27              : #include "egg/egg-timegm.h"
      28              : 
      29              : #include <stdarg.h>
      30              : #include <stdio.h>
      31              : #include <stdlib.h>
      32              : #include <string.h>
      33              : 
      34              : 
      35              : CK_RV
      36           27 : gkm_attribute_get_bool (CK_ATTRIBUTE_PTR attr, gboolean *value)
      37              : {
      38              :         CK_BBOOL* bool;
      39              : 
      40           27 :         g_return_val_if_fail (attr, CKR_GENERAL_ERROR);
      41           27 :         g_return_val_if_fail (value, CKR_GENERAL_ERROR);
      42              : 
      43           27 :         if (attr->ulValueLen != sizeof (CK_BBOOL) || attr->pValue == NULL)
      44            2 :                 return CKR_ATTRIBUTE_VALUE_INVALID;
      45              : 
      46           25 :         bool = attr->pValue;
      47           25 :         *value = *bool ? TRUE : FALSE;
      48           25 :         return CKR_OK;
      49              : }
      50              : 
      51              : CK_RV
      52            0 : gkm_attribute_get_ulong (CK_ATTRIBUTE_PTR attr, CK_ULONG *value)
      53              : {
      54              :         CK_ULONG* ulong;
      55              : 
      56            0 :         g_return_val_if_fail (attr, CKR_GENERAL_ERROR);
      57            0 :         g_return_val_if_fail (value, CKR_GENERAL_ERROR);
      58              : 
      59            0 :         if (attr->ulValueLen != sizeof (CK_ULONG) || attr->pValue == NULL)
      60            0 :                 return CKR_ATTRIBUTE_VALUE_INVALID;
      61              : 
      62            0 :         ulong = attr->pValue;
      63            0 :         *value = *ulong;
      64            0 :         return CKR_OK;
      65              : }
      66              : 
      67              : CK_RV
      68            4 : gkm_attribute_get_time (CK_ATTRIBUTE_PTR attr, glong *when)
      69              : {
      70              :         struct tm tm;
      71              :         gchar buf[15];
      72              :         time_t time;
      73              : 
      74            4 :         g_return_val_if_fail (attr, CKR_GENERAL_ERROR);
      75            4 :         g_return_val_if_fail (when, CKR_GENERAL_ERROR);
      76              : 
      77            4 :         if (attr->ulValueLen == 0) {
      78            1 :                 *when = (glong)-1;
      79            1 :                 return CKR_OK;
      80              :         }
      81              : 
      82            3 :         if (!attr->pValue || attr->ulValueLen != 16)
      83            1 :                 return CKR_ATTRIBUTE_VALUE_INVALID;
      84              : 
      85            2 :         memset (&tm, 0, sizeof (tm));
      86            2 :         memcpy (buf, attr->pValue, 14);
      87            2 :         buf[14] = 0;
      88              : 
      89            2 :         if (!strptime(buf, "%Y%m%d%H%M%S", &tm))
      90            1 :                 return CKR_ATTRIBUTE_VALUE_INVALID;
      91              : 
      92              :         /* Convert to seconds since epoch */
      93            1 :         time = timegm (&tm);
      94            1 :         if (time < 0)
      95            0 :                 return CKR_ATTRIBUTE_VALUE_INVALID;
      96              : 
      97            1 :         *when = time;
      98            1 :         return CKR_OK;
      99              : }
     100              : 
     101              : CK_RV
     102           83 : gkm_attribute_get_string (CK_ATTRIBUTE_PTR attr, gchar **value)
     103              : {
     104           83 :         g_return_val_if_fail (attr, CKR_GENERAL_ERROR);
     105           83 :         g_return_val_if_fail (value, CKR_GENERAL_ERROR);
     106              : 
     107           83 :         if (attr->ulValueLen == 0) {
     108            1 :                 *value = NULL;
     109            1 :                 return CKR_OK;
     110              :         }
     111              : 
     112           82 :         if (!attr->pValue)
     113            1 :                 return CKR_ATTRIBUTE_VALUE_INVALID;
     114              : 
     115           81 :         if (!g_utf8_validate (attr->pValue, attr->ulValueLen, NULL))
     116            1 :                 return CKR_ATTRIBUTE_VALUE_INVALID;
     117              : 
     118           80 :         *value = g_strndup (attr->pValue, attr->ulValueLen);
     119           80 :         return CKR_OK;
     120              : }
     121              : 
     122              : CK_RV
     123            1 : gkm_attribute_get_bytes (CK_ATTRIBUTE_PTR attr, GBytes **value)
     124              : {
     125            1 :         g_return_val_if_fail (attr, CKR_GENERAL_ERROR);
     126            1 :         g_return_val_if_fail (value, CKR_GENERAL_ERROR);
     127              : 
     128            1 :         if (attr->ulValueLen == 0) {
     129            0 :                 *value = NULL;
     130            0 :                 return CKR_OK;
     131              :         }
     132              : 
     133            1 :         if (!attr->pValue)
     134            0 :                 return CKR_ATTRIBUTE_VALUE_INVALID;
     135              : 
     136            1 :         *value = g_bytes_new (attr->pValue, attr->ulValueLen);
     137            1 :         return CKR_OK;
     138              : }
     139              : 
     140              : CK_RV
     141           16 : gkm_attribute_get_mpi (CK_ATTRIBUTE_PTR attr, gcry_mpi_t *value)
     142              : {
     143              :         gcry_error_t gcry;
     144              : 
     145           16 :         g_return_val_if_fail (attr, CKR_GENERAL_ERROR);
     146           16 :         g_return_val_if_fail (value, CKR_GENERAL_ERROR);
     147              : 
     148           16 :         gcry = gcry_mpi_scan (value, GCRYMPI_FMT_USG, attr->pValue, attr->ulValueLen, NULL);
     149           16 :         if (gcry != 0)
     150            0 :                 return CKR_ATTRIBUTE_VALUE_INVALID;
     151              : 
     152           16 :         return CKR_OK;
     153              : }
     154              : 
     155              : CK_RV
     156            6 : gkm_attribute_get_template (CK_ATTRIBUTE_PTR attr, GArray **template)
     157              : {
     158              :         CK_ULONG n_attrs;
     159              : 
     160            6 :         g_return_val_if_fail (attr, CKR_GENERAL_ERROR);
     161            6 :         g_return_val_if_fail (attr, CKR_GENERAL_ERROR);
     162              : 
     163              :         /* Validate everything first */
     164            6 :         if (attr->ulValueLen % sizeof (CK_ATTRIBUTE) != 0)
     165            0 :                 return CKR_ATTRIBUTE_VALUE_INVALID;
     166              : 
     167            6 :         n_attrs = attr->ulValueLen / sizeof (CK_ATTRIBUTE);
     168            6 :         if (n_attrs != 0 && !attr->pValue)
     169            0 :                 return CKR_ATTRIBUTE_VALUE_INVALID;
     170              : 
     171            6 :         *template = gkm_template_new (attr->pValue, n_attrs);
     172            6 :         return CKR_OK;
     173              : }
     174              : 
     175              : CK_RV
     176            3 : gkm_attribute_set_empty (CK_ATTRIBUTE_PTR attr)
     177              : {
     178            3 :         return gkm_attribute_set_data (attr, "", 0);
     179              : }
     180              : 
     181              : CK_RV
     182          248 : gkm_attribute_set_bool (CK_ATTRIBUTE_PTR attr, CK_BBOOL value)
     183              : {
     184          248 :         return gkm_attribute_set_data (attr, &value, sizeof (CK_BBOOL));
     185              : }
     186              : 
     187              : CK_RV
     188         5907 : gkm_attribute_set_ulong (CK_ATTRIBUTE_PTR attr, CK_ULONG value)
     189              : {
     190         5907 :         return gkm_attribute_set_data (attr, &value, sizeof (CK_ULONG));
     191              : }
     192              : 
     193              : CK_RV
     194         5158 : gkm_attribute_set_string (CK_ATTRIBUTE_PTR attr, const gchar* string)
     195              : {
     196        10313 :         return gkm_attribute_set_data (attr, (CK_VOID_PTR)string,
     197         5155 :                                        string ? strlen (string) : 0);
     198              : }
     199              : 
     200              : CK_RV
     201            4 : gkm_attribute_set_date (CK_ATTRIBUTE_PTR attr, time_t time)
     202              : {
     203              :         CK_DATE date;
     204              :         struct tm tm;
     205              :         gchar buf[16];
     206              : 
     207              :         /* 'Empty' date as defined in PKCS#11 */
     208            4 :         if (time == (time_t)-1)
     209            1 :                 return gkm_attribute_set_data (attr, NULL, 0);
     210              : 
     211            3 :         if (!attr->pValue) {
     212            1 :                 attr->ulValueLen = sizeof (CK_DATE);
     213            1 :                 return CKR_OK;
     214              :         }
     215              : 
     216            2 :         if (!gmtime_r (&time, &tm))
     217            0 :                 g_return_val_if_reached (CKR_GENERAL_ERROR);
     218              : 
     219              :         g_assert (sizeof (date.year) == 4);
     220            2 :         if (G_UNLIKELY (snprintf ((char*)buf, 5, "%04d", 1900 + tm.tm_year) < 0))
     221            0 :                 abort ();
     222            2 :         memcpy (date.year, buf, 4);
     223              : 
     224              :         g_assert (sizeof (date.month) == 2);
     225            2 :         if (G_UNLIKELY (snprintf ((char*)buf, 3, "%02d", tm.tm_mon + 1) < 0))
     226            0 :                 abort ();
     227            2 :         memcpy (date.month, buf, 2);
     228              : 
     229              :         g_assert (sizeof (date.day) == 2);
     230            2 :         if (G_UNLIKELY (snprintf ((char*)buf, 3, "%02d", tm.tm_mday) < 0))
     231            0 :                 abort ();
     232            2 :         memcpy (date.day, buf, 2);
     233              : 
     234            2 :         return gkm_attribute_set_data (attr, &date, sizeof (date));
     235              : }
     236              : 
     237              : CK_RV
     238            9 : gkm_attribute_set_time (CK_ATTRIBUTE_PTR attr, glong when)
     239              : {
     240              :         struct tm tm;
     241              :         gchar buf[20];
     242              : 
     243              :         /* 'Empty' time as defined in PKCS#11 */
     244            9 :         if (when == (glong)-1)
     245            1 :                 return gkm_attribute_set_data (attr, NULL, 0);
     246              : 
     247            8 :         if (!attr->pValue) {
     248            3 :                 attr->ulValueLen = 16;
     249            3 :                 return CKR_OK;
     250              :         }
     251              : 
     252            5 :         time_t time = when;
     253            5 :         if (!gmtime_r (&time, &tm))
     254            0 :                 g_return_val_if_reached (CKR_GENERAL_ERROR);
     255              : 
     256            5 :         if (!strftime(buf, sizeof (buf), "%Y%m%d%H%M%S00", &tm))
     257            0 :                 g_return_val_if_reached (CKR_GENERAL_ERROR);
     258              : 
     259            5 :         return gkm_attribute_set_data (attr, buf, 16);
     260              : }
     261              : 
     262              : CK_RV
     263        11572 : gkm_attribute_set_data (CK_ATTRIBUTE_PTR attr, gconstpointer value, gsize n_value)
     264              : {
     265        11572 :         CK_RV rv = gkm_util_return_data (attr->pValue, &(attr->ulValueLen), value, n_value);
     266        11572 :         if (rv == CKR_BUFFER_TOO_SMALL)
     267            6 :                 attr->ulValueLen = (CK_ULONG)-1;
     268        11572 :         return rv;
     269              : }
     270              : 
     271              : CK_RV
     272           66 : gkm_attribute_set_bytes (CK_ATTRIBUTE_PTR attr,
     273              :                          GBytes *value)
     274              : {
     275           66 :         return gkm_attribute_set_data (attr, g_bytes_get_data (value, NULL),
     276              :                                        g_bytes_get_size (value));
     277              : }
     278              : 
     279              : CK_RV
     280           10 : gkm_attribute_set_mpi (CK_ATTRIBUTE_PTR attr, gcry_mpi_t mpi)
     281              : {
     282              :         gsize len;
     283              :         gcry_error_t gcry;
     284              : 
     285           10 :         g_assert (attr);
     286           10 :         g_assert (mpi);
     287              : 
     288              :         /* Get the size */
     289           10 :         gcry = gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &len, mpi);
     290           10 :         g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
     291              : 
     292           10 :         if (!attr->pValue) {
     293            2 :                 attr->ulValueLen = len;
     294            2 :                 return CKR_OK;
     295              :         }
     296              : 
     297            8 :         if (len > attr->ulValueLen) {
     298            1 :                 attr->ulValueLen = (CK_ULONG)-1;
     299            1 :                 return CKR_BUFFER_TOO_SMALL;
     300              :         }
     301              : 
     302              :         /* Write in directly to attribute */
     303            7 :         gcry = gcry_mpi_print (GCRYMPI_FMT_USG, attr->pValue, len, &len, mpi);
     304            7 :         g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
     305              : 
     306            7 :         attr->ulValueLen = len;
     307            7 :         return CKR_OK;
     308              : }
     309              : 
     310              : CK_RV
     311            2 : gkm_attribute_set_template (CK_ATTRIBUTE_PTR attr, GArray *template)
     312              : {
     313              :         CK_ATTRIBUTE_PTR array;
     314              :         CK_ATTRIBUTE_PTR at;
     315              :         CK_RV rv;
     316              :         gulong len;
     317              :         gulong i;
     318              : 
     319            2 :         g_assert (attr);
     320            2 :         g_warn_if_fail ((attr->type & CKF_ARRAY_ATTRIBUTE) != 0);
     321              : 
     322            2 :         len = sizeof (CK_ATTRIBUTE) * template->len;
     323            2 :         if (!attr->pValue) {
     324            0 :                 attr->ulValueLen = len;
     325            0 :                 return CKR_OK;
     326            2 :         } else if (len > attr->ulValueLen) {
     327            2 :                 attr->ulValueLen = (CK_ULONG)-1;
     328            2 :                 return CKR_BUFFER_TOO_SMALL;
     329              :         }
     330              : 
     331            0 :         attr->ulValueLen = len;
     332            0 :         array = attr->pValue;
     333            0 :         rv = CKR_OK;
     334              : 
     335              :         /* Start working with individual elements */
     336            0 :         for (i = 0; i < template->len; ++i) {
     337            0 :                 at = &g_array_index (template, CK_ATTRIBUTE, i);
     338            0 :                 array[i].type = at->type;
     339            0 :                 if (!array[i].pValue) {
     340            0 :                         array[i].ulValueLen = at->ulValueLen;
     341            0 :                 } else if (array[i].ulValueLen < at->ulValueLen) {
     342            0 :                         array[i].ulValueLen = (CK_ULONG)-1;
     343            0 :                         rv = CKR_BUFFER_TOO_SMALL;
     344              :                 } else {
     345            0 :                         memcpy(array[i].pValue, at->pValue, at->ulValueLen);
     346            0 :                         array[i].ulValueLen = at->ulValueLen;
     347              :                 }
     348              :         }
     349              : 
     350            0 :         return rv;
     351              : }
     352              : 
     353              : CK_RV
     354           18 : gkm_attribute_set_checksum (CK_ATTRIBUTE_PTR attr, GChecksumType ctype,
     355              :                             gconstpointer data, gsize n_data)
     356              : {
     357              :         GChecksum *checksum;
     358              :         gssize length;
     359              :         gsize result;
     360              : 
     361           18 :         g_assert (attr);
     362              : 
     363           18 :         g_return_val_if_fail (data, CKR_GENERAL_ERROR);
     364           18 :         g_return_val_if_fail (n_data, CKR_GENERAL_ERROR);
     365              : 
     366           18 :         length = g_checksum_type_get_length (ctype);
     367           18 :         g_return_val_if_fail (length > 0, CKR_GENERAL_ERROR);
     368              : 
     369              :         /* Just asking for the length */
     370           18 :         if (!attr->pValue) {
     371            0 :                 attr->ulValueLen = length;
     372            0 :                 return CKR_OK;
     373              :         }
     374              : 
     375              :         /* Buffer is too short */
     376           18 :         if (length > attr->ulValueLen) {
     377            0 :                 attr->ulValueLen = length;
     378            0 :                 return CKR_BUFFER_TOO_SMALL;
     379              :         }
     380              : 
     381           18 :         checksum = g_checksum_new (ctype);
     382           18 :         g_checksum_update (checksum, data, n_data);
     383           18 :         result = attr->ulValueLen;
     384           18 :         g_checksum_get_digest (checksum, attr->pValue, &result);
     385           18 :         g_checksum_free (checksum);
     386           18 :         attr->ulValueLen = result;
     387           18 :         return CKR_OK;
     388              : }
     389              : 
     390              : gboolean
     391        20185 : gkm_attribute_equal (gconstpointer v1, gconstpointer v2)
     392              : {
     393        20185 :         const CK_ATTRIBUTE *a1 = v1;
     394        20185 :         const CK_ATTRIBUTE *a2 = v2;
     395              : 
     396        20185 :         g_assert (a1);
     397        20185 :         g_assert (a2);
     398              : 
     399        20185 :         if (a1 == a2)
     400        10498 :                 return TRUE;
     401         9687 :         if (a1->type != a2->type)
     402         3207 :                 return FALSE;
     403         6480 :         if (a1->ulValueLen != a2->ulValueLen)
     404            7 :                 return FALSE;
     405         6473 :         if (a1->pValue == a2->pValue)
     406            4 :                 return TRUE;
     407         6469 :         if (a1->ulValueLen == 0)
     408            1 :                 return TRUE;
     409              : 
     410         6468 :         g_assert (a1->pValue);
     411         6468 :         g_assert (a2->pValue);
     412              : 
     413         6468 :         return memcmp (a1->pValue, a2->pValue, a1->ulValueLen) == 0;
     414              : }
     415              : 
     416              : guint
     417        29314 : gkm_attribute_hash (gconstpointer v)
     418              : {
     419        29314 :         const CK_ATTRIBUTE *a = v;
     420              :         const signed char *p;
     421              :         guint i, h;
     422              : 
     423        29314 :         g_assert (a);
     424              : 
     425        29314 :         p = (const signed char*)&(a->type);
     426        29314 :         h = *p;
     427       263826 :         for(i = 0; i < sizeof (CK_ATTRIBUTE_PTR); ++i)
     428       234512 :                 h = (h << 5) - h + *(p++);
     429              : 
     430        29314 :         p = a->pValue;
     431       264601 :         for(i = 0; i < a->ulValueLen; ++i)
     432       235287 :                 h = (h << 5) - h + *(p++);
     433              : 
     434        29314 :         return h;
     435              : }
     436              : 
     437              : gboolean
     438         2812 : gkm_attribute_consumed (CK_ATTRIBUTE_PTR attr)
     439              : {
     440         2812 :         g_return_val_if_fail (attr, FALSE);
     441         2812 :         return attr->type == (CK_ULONG)-1;
     442              : }
     443              : 
     444              : void
     445           46 : gkm_attribute_consume (CK_ATTRIBUTE_PTR attr)
     446              : {
     447           46 :         attr->type = (CK_ULONG)-1;
     448           46 : }
     449              : 
     450              : void
     451          577 : gkm_attributes_consume (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs, ...)
     452              : {
     453              :         CK_ATTRIBUTE_TYPE type;
     454              :         GArray *types;
     455              :         guint i, j;
     456              :         va_list va;
     457              : 
     458              :         /* Convert the var args into an array */
     459          577 :         types = g_array_new (FALSE, TRUE, sizeof (CK_ATTRIBUTE_TYPE));
     460          577 :         va_start (va, n_attrs);
     461         1807 :         while ((type = va_arg (va, CK_ATTRIBUTE_TYPE)) != G_MAXULONG)
     462         1230 :                  g_array_append_val (types, type);
     463          577 :         va_end (va);
     464              : 
     465              :         /* Consume each attribute whose type was in the var args */
     466         2719 :         for (i = 0; i < n_attrs; ++i) {
     467         2142 :                 if (gkm_attribute_consumed (&attrs[i]))
     468          742 :                         continue;
     469         3946 :                 for (j = 0; j < types->len; ++j) {
     470         2941 :                         if (attrs[i].type == g_array_index (types, CK_ATTRIBUTE_TYPE, j)) {
     471          395 :                                 attrs[i].type = (CK_ULONG)-1;
     472          395 :                                 break;
     473              :                         }
     474              :                 }
     475              :         }
     476              : 
     477          577 :         g_array_free (types, TRUE);
     478          577 : }
     479              : 
     480              : gboolean
     481         1026 : gkm_attributes_contains (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs, CK_ATTRIBUTE_PTR attr)
     482              : {
     483              :         CK_ULONG i;
     484              : 
     485         1026 :         g_assert (attrs || !n_attrs);
     486         1026 :         g_assert (attr);
     487              : 
     488         5037 :         for (i = 0; i < n_attrs; ++i) {
     489         4214 :                 if (gkm_attribute_equal (attr, &attrs[i]))
     490          203 :                         return TRUE;
     491              :         }
     492              : 
     493          823 :         return FALSE;
     494              : }
     495              : 
     496              : CK_ATTRIBUTE_PTR
     497         3549 : gkm_attributes_find (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs, CK_ATTRIBUTE_TYPE type)
     498              : {
     499              :         CK_ULONG i;
     500              : 
     501         3549 :         g_assert (attrs || !n_attrs);
     502              : 
     503        15902 :         for (i = 0; i < n_attrs; ++i) {
     504        14081 :                 if(attrs[i].type == type && attrs[i].ulValueLen != (CK_ULONG)-1)
     505         1728 :                         return &attrs[i];
     506              :         }
     507              : 
     508         1821 :         return NULL;
     509              : }
     510              : 
     511              : gboolean
     512          715 : gkm_attributes_find_boolean (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs, CK_ATTRIBUTE_TYPE type, gboolean *value)
     513              : {
     514              :         CK_ATTRIBUTE_PTR attr;
     515              : 
     516          715 :         g_assert (attrs || !n_attrs);
     517              : 
     518          715 :         attr = gkm_attributes_find (attrs, n_attrs, type);
     519          715 :         if (attr == NULL)
     520          424 :                 return FALSE;
     521              : 
     522          291 :         if (attr->ulValueLen != sizeof (CK_BBOOL))
     523            1 :                 return FALSE;
     524              : 
     525          290 :         if (value != NULL) {
     526              :                 CK_BBOOL bbool;
     527          290 :                 memcpy (&bbool, attr->pValue, sizeof (CK_BBOOL));
     528          290 :                 *value = bbool == CK_TRUE ? TRUE : FALSE;
     529              :         }
     530              : 
     531          290 :         return TRUE;
     532              : }
     533              : 
     534              : gboolean
     535          670 : gkm_attributes_find_ulong (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs, CK_ATTRIBUTE_TYPE type, gulong *value)
     536              : {
     537              :         CK_ATTRIBUTE_PTR attr;
     538              : 
     539          670 :         g_assert (attrs || !n_attrs);
     540              : 
     541          670 :         attr = gkm_attributes_find (attrs, n_attrs, type);
     542          670 :         if (attr == NULL)
     543          401 :                 return FALSE;
     544              : 
     545          269 :         if (attr->ulValueLen != sizeof (CK_ULONG))
     546            1 :                 return FALSE;
     547              : 
     548          268 :         if (value != NULL) {
     549              :                 CK_ULONG ulong;
     550          268 :                 memcpy (&ulong, attr->pValue, sizeof (CK_ULONG));
     551          268 :                 *value = ulong;
     552              :         }
     553              : 
     554          268 :         return TRUE;
     555              : }
     556              : 
     557              : gboolean
     558           15 : gkm_attributes_find_mpi (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs,
     559              :                          CK_ATTRIBUTE_TYPE type, gcry_mpi_t *value)
     560              : {
     561              :         CK_ATTRIBUTE_PTR attr;
     562              : 
     563           15 :         g_assert (attrs || !n_attrs);
     564              : 
     565           15 :         attr = gkm_attributes_find (attrs, n_attrs, type);
     566           15 :         if (attr == NULL)
     567            1 :                 return FALSE;
     568              : 
     569           14 :         return gkm_attribute_get_mpi (attr, value) == CKR_OK;
     570              : }
     571              : 
     572              : gboolean
     573           89 : gkm_attributes_find_string (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs,
     574              :                             CK_ATTRIBUTE_TYPE type, gchar **value)
     575              : {
     576              :         CK_ATTRIBUTE_PTR attr;
     577              : 
     578           89 :         g_return_val_if_fail (attrs || !n_attrs, FALSE);
     579              : 
     580           89 :         attr = gkm_attributes_find (attrs, n_attrs, type);
     581           89 :         if (attr == NULL)
     582           46 :                 return FALSE;
     583              : 
     584           43 :         return gkm_attribute_get_string (attr, value) == CKR_OK;
     585              : }
     586              : 
     587              : /* Need to get DER encoded EC parameters and point */
     588              : gboolean
     589            1 : gkm_attributes_find_bytes (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs,
     590              :                            CK_ATTRIBUTE_TYPE type, GBytes **value)
     591              : {
     592              :         CK_ATTRIBUTE_PTR attr;
     593              : 
     594            1 :         g_return_val_if_fail (attrs || !n_attrs, FALSE);
     595              : 
     596            1 :         attr = gkm_attributes_find (attrs, n_attrs, type);
     597            1 :         if (attr == NULL)
     598            0 :                 return FALSE;
     599              : 
     600            1 :         return gkm_attribute_get_bytes (attr, value) == CKR_OK;
     601              : }
     602              : 
     603              : GArray*
     604          598 : gkm_template_new (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
     605              : {
     606          598 :         GArray *template = g_array_new (FALSE, FALSE, sizeof (CK_ATTRIBUTE));
     607              :         CK_ATTRIBUTE_PTR pat;
     608              :         gulong i;
     609              : 
     610          598 :         g_return_val_if_fail (attrs || !n_attrs, NULL);
     611              : 
     612          598 :         g_array_append_vals (template, attrs, n_attrs);
     613         1935 :         for (i = 0; i < n_attrs; ++i) {
     614         1337 :                 pat = &g_array_index (template, CK_ATTRIBUTE, i);
     615         1337 :                 if (pat->pValue) {
     616         1321 :                         g_return_val_if_fail (pat->ulValueLen != (CK_ULONG)-1, NULL);
     617         1321 :                         pat->pValue = g_memdup (pat->pValue, pat->ulValueLen ? pat->ulValueLen : 1);
     618              :                 }
     619              :         }
     620              : 
     621          598 :         return template;
     622              : }
     623              : 
     624              : void
     625         1550 : gkm_template_set (GArray *template, CK_ATTRIBUTE_PTR attr)
     626              : {
     627              :         CK_ATTRIBUTE at;
     628              :         guint i;
     629              : 
     630         1550 :         g_return_if_fail (template);
     631         1550 :         g_return_if_fail (attr);
     632         1550 :         g_return_if_fail (attr->ulValueLen != (CK_ULONG)-1);
     633              : 
     634              :         /* Remove any previous value */
     635         6449 :         for (i = 0; i < template->len; ++i) {
     636         4909 :                 if (g_array_index (template, CK_ATTRIBUTE, i).type == attr->type) {
     637           10 :                         g_free (g_array_index (template, CK_ATTRIBUTE, i).pValue);
     638           10 :                         g_array_remove_index_fast (template, i);
     639           10 :                         break;
     640              :                 }
     641              :         }
     642              : 
     643              :         /* Add a new attribute */
     644         1550 :         memcpy (&at, attr, sizeof (at));
     645         1550 :         if (at.pValue)
     646         1540 :                 at.pValue = g_memdup (at.pValue, at.ulValueLen ? at.ulValueLen : 1);
     647         1550 :         g_array_append_vals (template, &at, 1);
     648              : }
     649              : 
     650              : void
     651          179 : gkm_template_set_value (GArray *template, CK_ATTRIBUTE_TYPE type,
     652              :                         CK_VOID_PTR value, CK_ULONG length)
     653              : {
     654              :         CK_ATTRIBUTE attr;
     655          179 :         g_return_if_fail (template);
     656              : 
     657          179 :         attr.type = type;
     658          179 :         attr.pValue = value;
     659          179 :         attr.ulValueLen = length;
     660          179 :         gkm_template_set (template, &attr);
     661              : }
     662              : 
     663              : void
     664          523 : gkm_template_set_string (GArray *template, CK_ATTRIBUTE_TYPE type, const gchar *value)
     665              : {
     666              :         CK_ATTRIBUTE attr;
     667          523 :         g_return_if_fail (template);
     668          523 :         g_return_if_fail (value);
     669              : 
     670          523 :         attr.type = type;
     671          523 :         attr.pValue = (CK_VOID_PTR)value;
     672          523 :         attr.ulValueLen = strlen (value);
     673          523 :         gkm_template_set (template, &attr);
     674              : 
     675              : }
     676              : void
     677          239 : gkm_template_set_ulong (GArray *template, CK_ATTRIBUTE_TYPE type, CK_ULONG value)
     678              : {
     679              :         CK_ATTRIBUTE attr;
     680          239 :         g_return_if_fail (template);
     681              : 
     682          239 :         attr.type = type;
     683          239 :         attr.pValue = &value;
     684          239 :         attr.ulValueLen = sizeof (value);
     685          239 :         gkm_template_set (template, &attr);
     686              : 
     687              : }
     688              : 
     689              : void
     690          554 : gkm_template_set_boolean (GArray *template, CK_ATTRIBUTE_TYPE type, CK_BBOOL value)
     691              : {
     692              :         CK_ATTRIBUTE attr;
     693          554 :         g_return_if_fail (template);
     694              : 
     695          554 :         attr.type = type;
     696          554 :         attr.pValue = &value;
     697          554 :         attr.ulValueLen = sizeof (value);
     698          554 :         gkm_template_set (template, &attr);
     699              : }
     700              : 
     701              : void
     702          598 : gkm_template_free (GArray *template)
     703              : {
     704              :         guint i;
     705              : 
     706          598 :         if (!template)
     707            0 :                 return;
     708              : 
     709         3475 :         for (i = 0; i < template->len; ++i)
     710         2877 :                 g_free (g_array_index (template, CK_ATTRIBUTE, i).pValue);
     711          598 :         g_array_free (template, TRUE);
     712              : }
     713              : 
     714              : CK_ATTRIBUTE_PTR
     715         1497 : gkm_template_find (GArray *template, CK_ATTRIBUTE_TYPE type)
     716              : {
     717         1497 :         g_return_val_if_fail (template, NULL);
     718         1497 :         return gkm_attributes_find ((CK_ATTRIBUTE_PTR)template->data, template->len, type);
     719              : }
     720              : 
     721              : gboolean
     722          146 : gkm_template_find_boolean (GArray *template, CK_ATTRIBUTE_TYPE type, gboolean *value)
     723              : {
     724          146 :         g_return_val_if_fail (template, FALSE);
     725          146 :         return gkm_attributes_find_boolean ((CK_ATTRIBUTE_PTR)template->data, template->len, type, value);
     726              : }
     727              : 
     728              : gboolean
     729          103 : gkm_template_find_ulong (GArray *template, CK_ATTRIBUTE_TYPE type, gulong *value)
     730              : {
     731          103 :         g_return_val_if_fail (template, FALSE);
     732          103 :         return gkm_attributes_find_ulong ((CK_ATTRIBUTE_PTR)template->data, template->len, type, value);
     733              : }
        

Generated by: LCOV version 2.0-1